Skip to content

Commit 8fa8bec

Browse files
committed
Add byte_size in ByteRepr to capture C size
1 parent 0dca34e commit 8fa8bec

3 files changed

Lines changed: 69 additions & 48 deletions

File tree

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,8 @@ static bool recordImplementsByteRepr(const clang::RecordDecl *decl) {
566566
void ConverterRefCount::AddByteReprTrait(const clang::RecordDecl *decl) {
567567
auto struct_name = GetRecordName(decl);
568568

569-
if (!recordImplementsByteRepr(decl)) {
569+
570+
if (!TypeImplementsByteRepr(ctx_.getCanonicalTagType(decl))) {
570571
StrCat(std::format("impl ByteRepr for {}", struct_name));
571572
PushBrace brace(*this);
572573
return;
@@ -577,6 +578,9 @@ void ConverterRefCount::AddByteReprTrait(const clang::RecordDecl *decl) {
577578

578579
const auto &layout = ctx_.getASTRecordLayout(decl);
579580

581+
StrCat(std::format("fn byte_size() -> usize {{ {} }}",
582+
ctx_.getTypeSize(ctx_.getCanonicalTagType(decl)) / 8));
583+
580584
StrCat("fn to_bytes(&self, buf: &mut [u8])");
581585
{
582586
PushBrace fn_brace(*this);

‎libcc2rs/src/rc.rs‎

Lines changed: 54 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ use crate::reinterpret::{ByteRepr, OriginalAlloc, SingleOriginalAlloc, SliceOrig
1616

1717
pub type Value<T> = Rc<RefCell<T>>;
1818

19+
struct ReinterpretedView {
20+
// Pointer to the source of reinterpret
21+
alloc: Rc<dyn OriginalAlloc>,
22+
// C++ size of the reinterpreted view
23+
elem_byte_size: usize,
24+
}
25+
1926
#[derive(Default)]
2027
enum PtrKind<T> {
2128
#[default]
@@ -25,7 +32,7 @@ enum PtrKind<T> {
2532
HeapSingle(Weak<RefCell<T>>),
2633
HeapArray(Weak<RefCell<Box<[T]>>>),
2734
Vec(Weak<RefCell<Vec<T>>>),
28-
Reinterpreted(Rc<dyn OriginalAlloc>),
35+
Reinterpreted(Rc<ReinterpretedView>),
2936
}
3037

3138
pub enum StrongPtr<T> {
@@ -59,7 +66,7 @@ impl<T: ByteRepr> StrongPtr<T> {
5966
cell,
6067
} => {
6168
// Read-through: always re-read from the original allocation.
62-
let mut buf = vec![0u8; std::mem::size_of::<T>()];
69+
let mut buf = vec![0u8; T::byte_size()];
6370
alloc.read_bytes(*byte_offset, &mut buf);
6471
*cell.borrow_mut() = Some(T::from_bytes(&buf));
6572
Ref::map(cell.borrow(), |opt| opt.as_ref().unwrap())
@@ -77,8 +84,8 @@ impl<T> fmt::Debug for PtrKind<T> {
7784
PtrKind::HeapSingle(w) => write!(f, "HeapSingle({:?})", w.as_ptr()),
7885
PtrKind::StackArray(w) => write!(f, "StackArray({:?})", w.as_ptr()),
7986
PtrKind::HeapArray(w) => write!(f, "HeapArray({:?})", w.as_ptr()),
80-
PtrKind::Reinterpreted(data) => {
81-
write!(f, "Reinterpreted(0x{:x})", data.address())
87+
PtrKind::Reinterpreted(view) => {
88+
write!(f, "Reinterpreted(0x{:x})", view.alloc.address())
8289
}
8390
}
8491
}
@@ -93,7 +100,7 @@ impl<T> Clone for PtrKind<T> {
93100
PtrKind::HeapSingle(weak) => PtrKind::HeapSingle(weak.clone()),
94101
PtrKind::StackArray(weak) => PtrKind::StackArray(weak.clone()),
95102
PtrKind::HeapArray(weak) => PtrKind::HeapArray(weak.clone()),
96-
PtrKind::Reinterpreted(data) => PtrKind::Reinterpreted(Rc::clone(data)),
103+
PtrKind::Reinterpreted(view) => PtrKind::Reinterpreted(Rc::clone(view)),
97104
}
98105
}
99106
}
@@ -105,7 +112,7 @@ impl<T> PtrKind<T> {
105112
PtrKind::StackSingle(w) | PtrKind::HeapSingle(w) => w.as_ptr() as usize,
106113
PtrKind::Vec(w) => w.as_ptr() as usize,
107114
PtrKind::StackArray(w) | PtrKind::HeapArray(w) => w.as_ptr() as usize,
108-
PtrKind::Reinterpreted(data) => data.address(),
115+
PtrKind::Reinterpreted(view) => view.alloc.address(),
109116
}
110117
}
111118
}
@@ -251,40 +258,40 @@ impl<T> Ptr<T> {
251258
#[inline]
252259
fn elem_step(&self) -> usize {
253260
match &self.kind {
254-
PtrKind::Reinterpreted(_) => std::mem::size_of::<T>(),
261+
PtrKind::Reinterpreted(view) => view.elem_byte_size,
255262
_ => 1,
256263
}
257264
}
258265

259266
#[inline]
260267
pub fn len(&self) -> usize {
261-
match self.kind {
268+
match &self.kind {
262269
PtrKind::Null => 0,
263270
PtrKind::StackSingle(_) | PtrKind::HeapSingle(_) => 1,
264-
PtrKind::Vec(ref weak) => weak.upgrade().expect("ub: dangling pointer").borrow().len(),
265-
PtrKind::StackArray(ref weak) | PtrKind::HeapArray(ref weak) => {
271+
PtrKind::Vec(weak) => weak.upgrade().expect("ub: dangling pointer").borrow().len(),
272+
PtrKind::StackArray(weak) | PtrKind::HeapArray(weak) => {
266273
weak.upgrade().expect("ub: dangling pointer").borrow().len()
267274
}
268-
PtrKind::Reinterpreted(ref data) => data.total_byte_len() / std::mem::size_of::<T>(),
275+
PtrKind::Reinterpreted(view) => view.alloc.total_byte_len() / view.elem_byte_size,
269276
}
270277
}
271278

272279
#[inline]
273280
pub fn is_empty(&self) -> bool {
274-
match self.kind {
281+
match &self.kind {
275282
PtrKind::Null => true,
276283
PtrKind::StackSingle(_) | PtrKind::HeapSingle(_) => false,
277-
PtrKind::Vec(ref weak) => weak
284+
PtrKind::Vec(weak) => weak
278285
.upgrade()
279286
.expect("ub: dangling pointer")
280287
.borrow()
281288
.is_empty(),
282-
PtrKind::StackArray(ref weak) | PtrKind::HeapArray(ref weak) => weak
289+
PtrKind::StackArray(weak) | PtrKind::HeapArray(weak) => weak
283290
.upgrade()
284291
.expect("ub: dangling pointer")
285292
.borrow()
286293
.is_empty(),
287-
PtrKind::Reinterpreted(ref data) => self.offset >= data.total_byte_len(),
294+
PtrKind::Reinterpreted(view) => self.offset >= view.alloc.total_byte_len(),
288295
}
289296
}
290297

@@ -339,8 +346,8 @@ impl<T> Ptr<T> {
339346
rc: weak.upgrade().expect("ub: dangling pointer"),
340347
offset: self.offset,
341348
},
342-
PtrKind::Reinterpreted(data) => StrongPtr::Reinterpreted {
343-
alloc: Rc::clone(data),
349+
PtrKind::Reinterpreted(view) => StrongPtr::Reinterpreted {
350+
alloc: Rc::clone(&view.alloc),
344351
byte_offset: self.offset,
345352
cell: RefCell::new(None),
346353
},
@@ -365,10 +372,10 @@ impl<T> Ptr<T> {
365372
let rc = weak.upgrade().expect("ub: dangling pointer");
366373
rc.borrow_mut()[self.offset] = value;
367374
}
368-
PtrKind::Reinterpreted(data) => {
369-
let mut buf = vec![0u8; std::mem::size_of::<T>()];
375+
PtrKind::Reinterpreted(view) => {
376+
let mut buf = vec![0u8; T::byte_size()];
370377
value.to_bytes(&mut buf);
371-
data.write_bytes(self.offset, &buf);
378+
view.alloc.write_bytes(self.offset, &buf);
372379
}
373380
}
374381
}
@@ -391,30 +398,34 @@ impl<T> Ptr<T> {
391398
return self_any.downcast_ref::<Ptr<U>>().unwrap().clone();
392399
}
393400

394-
if std::mem::size_of::<U>() == 0 {
401+
if U::byte_size() == 0 {
395402
panic!("cannot reinterpret_cast to zero-sized type");
396403
}
397404

405+
let src_byte_off = self.offset.wrapping_mul(T::byte_size());
398406
let (alloc, abs_byte_off): (Rc<dyn OriginalAlloc>, usize) = match &self.kind {
399407
PtrKind::Null => return Ptr::null(),
400408
PtrKind::StackSingle(weak) | PtrKind::HeapSingle(weak) => (
401409
Rc::new(SingleOriginalAlloc { weak: weak.clone() }),
402-
self.byte_offset(),
410+
src_byte_off,
403411
),
404412
PtrKind::Vec(weak) => (
405413
Rc::new(SliceOriginalAlloc { weak: weak.clone() }),
406-
self.byte_offset(),
414+
src_byte_off,
407415
),
408416
PtrKind::StackArray(weak) | PtrKind::HeapArray(weak) => (
409417
Rc::new(SliceOriginalAlloc { weak: weak.clone() }),
410-
self.byte_offset(),
418+
src_byte_off,
411419
),
412-
PtrKind::Reinterpreted(data) => (Rc::clone(data), self.offset),
420+
PtrKind::Reinterpreted(view) => (Rc::clone(&view.alloc), self.offset),
413421
};
414422

415423
Ptr {
416424
offset: abs_byte_off,
417-
kind: PtrKind::Reinterpreted(alloc),
425+
kind: PtrKind::Reinterpreted(Rc::new(ReinterpretedView {
426+
alloc,
427+
elem_byte_size: U::byte_size(),
428+
})),
418429
}
419430
}
420431
}
@@ -441,13 +452,13 @@ impl<T> Ptr<T> {
441452
let mut borrow = rc.borrow_mut();
442453
f(&mut borrow[self.offset])
443454
}
444-
PtrKind::Reinterpreted(data) => {
445-
let mut buf = vec![0u8; std::mem::size_of::<T>()];
446-
data.read_bytes(self.offset, &mut buf);
455+
PtrKind::Reinterpreted(view) => {
456+
let mut buf = vec![0u8; T::byte_size()];
457+
view.alloc.read_bytes(self.offset, &mut buf);
447458
let mut val = T::from_bytes(&buf);
448459
let ret = f(&mut val);
449460
val.to_bytes(&mut buf);
450-
data.write_bytes(self.offset, &buf);
461+
view.alloc.write_bytes(self.offset, &buf);
451462
ret
452463
}
453464
}
@@ -474,9 +485,9 @@ impl<T> Ptr<T> {
474485
let borrow = rc.borrow();
475486
f(&borrow[self.offset])
476487
}
477-
PtrKind::Reinterpreted(data) => {
478-
let mut buf = vec![0u8; std::mem::size_of::<T>()];
479-
data.read_bytes(self.offset, &mut buf);
488+
PtrKind::Reinterpreted(view) => {
489+
let mut buf = vec![0u8; T::byte_size()];
490+
view.alloc.read_bytes(self.offset, &mut buf);
480491
let val = T::from_bytes(&buf);
481492
f(&val)
482493
}
@@ -501,9 +512,9 @@ impl<T: Clone + ByteRepr> Ptr<T> {
501512
PtrKind::StackArray(ref weak) | PtrKind::HeapArray(ref weak) => {
502513
weak.upgrade().expect("ub: dangling pointer").borrow()[self.offset].clone()
503514
}
504-
PtrKind::Reinterpreted(ref data) => {
505-
let mut buf = vec![0u8; std::mem::size_of::<T>()];
506-
data.read_bytes(self.offset, &mut buf);
515+
PtrKind::Reinterpreted(ref view) => {
516+
let mut buf = vec![0u8; T::byte_size()];
517+
view.alloc.read_bytes(self.offset, &mut buf);
507518
T::from_bytes(&buf)
508519
}
509520
}
@@ -535,7 +546,7 @@ impl<T: std::cmp::Ord> Ptr<T> {
535546
let strong = weak.upgrade().expect("ub: dangling pointer");
536547
(*strong.borrow_mut())[self.get_offset()..last].sort();
537548
}
538-
PtrKind::Reinterpreted(..) => {
549+
PtrKind::Reinterpreted(_) => {
539550
panic!("sorting not supported for reinterpreted pointers")
540551
}
541552
}
@@ -580,7 +591,7 @@ impl<T: Clone> Ptr<T> {
580591
let mut borrow = strong.borrow_mut();
581592
sort(&mut borrow, self.get_offset(), last, &mut cmp);
582593
}
583-
PtrKind::Reinterpreted(..) => {
594+
PtrKind::Reinterpreted(_) => {
584595
panic!("sorting not supported for reinterpreted pointers")
585596
}
586597
}
@@ -856,7 +867,7 @@ impl<T> ToOwnedOption<T, T> for Ptr<T> {
856867
}
857868
PtrKind::Vec(_) => panic!("Can't own a vector"),
858869
PtrKind::HeapArray(_) => panic!("Can't own an array variable as single"),
859-
PtrKind::Reinterpreted(..) => panic!("Can't own a reinterpreted pointer"),
870+
PtrKind::Reinterpreted(_) => panic!("Can't own a reinterpreted pointer"),
860871
}
861872
}
862873
}
@@ -882,7 +893,7 @@ impl<T> ToOwnedOption<T, Box<[T]>> for Ptr<T> {
882893
}
883894
PtrKind::Vec(_) => panic!("Can't own a vector"),
884895
PtrKind::HeapSingle(_) => panic!("Can't own a single variable as an array"),
885-
PtrKind::Reinterpreted(..) => panic!("Can't own a reinterpreted pointer"),
896+
PtrKind::Reinterpreted(_) => panic!("Can't own a reinterpreted pointer"),
886897
}
887898
}
888899
}
@@ -898,7 +909,7 @@ impl<T> fmt::Debug for Ptr<T> {
898909
(Weak::as_ptr(w) as usize).wrapping_add(self.byte_offset())
899910
}
900911
PtrKind::Vec(w) => (Weak::as_ptr(w) as usize).wrapping_add(self.byte_offset()),
901-
PtrKind::Reinterpreted(data) => data.address().wrapping_add(self.byte_offset()),
912+
PtrKind::Reinterpreted(view) => view.alloc.address().wrapping_add(self.byte_offset()),
902913
};
903914
write!(f, "0x{:x}", addr)
904915
}
@@ -994,9 +1005,9 @@ impl Ptr<u8> {
9941005
let raw = strong.borrow();
9951006
raw[start..end].to_vec()
9961007
}
997-
PtrKind::Reinterpreted(ref data) => {
1008+
PtrKind::Reinterpreted(ref view) => {
9981009
let mut buf = vec![0u8; end.wrapping_sub(start)];
999-
data.read_bytes(start, &mut buf);
1010+
view.alloc.read_bytes(start, &mut buf);
10001011
buf
10011012
}
10021013
}

‎libcc2rs/src/reinterpret.rs‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
use std::{cell::RefCell, rc::Weak};
55

66
pub trait ByteRepr: 'static {
7+
fn byte_size() -> usize
8+
where
9+
Self: Sized,
10+
{
11+
std::mem::size_of::<Self>()
12+
}
713
fn to_bytes(&self, _buf: &mut [u8]) {
814
panic!("ByteRepr not supported for this type");
915
}
@@ -83,7 +89,7 @@ pub trait OriginalAlloc {
8389
// Only serializes the overlapping elements, not the whole slice.
8490
fn slice_read_bytes<S: ByteRepr>(slice: &[S], byte_offset: usize, buf: &mut [u8]) {
8591
let len = buf.len();
86-
let elem_size = std::mem::size_of::<S>();
92+
let elem_size = S::byte_size();
8793
let first_elem = byte_offset / elem_size;
8894
let last_elem = (byte_offset + len).div_ceil(elem_size);
8995
let tmp_len = (last_elem - first_elem) * elem_size;
@@ -98,7 +104,7 @@ fn slice_read_bytes<S: ByteRepr>(slice: &[S], byte_offset: usize, buf: &mut [u8]
98104
// Write `data` at `byte_offset` into a slice of S elements.
99105
// Only deserializes/reserializes the overlapping elements.
100106
fn slice_write_bytes<S: ByteRepr>(slice: &mut [S], byte_offset: usize, data: &[u8]) {
101-
let elem_size = std::mem::size_of::<S>();
107+
let elem_size = S::byte_size();
102108
let mut elem_buf = vec![0u8; elem_size];
103109
let first_elem = byte_offset / elem_size;
104110
let num_elem = data.len().div_ceil(elem_size);
@@ -136,7 +142,7 @@ impl<T: ByteRepr> OriginalAlloc for SingleOriginalAlloc<T> {
136142
}
137143

138144
fn total_byte_len(&self) -> usize {
139-
std::mem::size_of::<T>()
145+
T::byte_size()
140146
}
141147

142148
fn address(&self) -> usize {
@@ -190,7 +196,7 @@ impl<T: AsSlice + 'static> OriginalAlloc for SliceOriginalAlloc<T> {
190196
fn total_byte_len(&self) -> usize {
191197
let rc = self.weak.upgrade().expect("ub: dangling pointer");
192198
let val = rc.borrow();
193-
std::mem::size_of_val(val.as_slice())
199+
val.as_slice().len() * <T::Elem as ByteRepr>::byte_size()
194200
}
195201

196202
fn address(&self) -> usize {

0 commit comments

Comments
 (0)