From 0dca34e1191b59795023ea7ddc0ca7119098adf0 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 24 Jun 2026 11:32:53 +0100 Subject: [PATCH 01/15] Use C size when size_of diverges between C and Rust --- cpp2rust/converter/converter_lib.cpp | 36 +++++++++++++++++++ cpp2rust/converter/converter_lib.h | 4 +++ .../converter/models/converter_refcount.cpp | 14 ++++++++ .../converter/models/converter_refcount.h | 3 ++ 4 files changed, 57 insertions(+) diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 43e380f1..4c4901a4 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -200,6 +200,42 @@ bool IsMut(clang::QualType qual_type) { qual_type->getPointeeType().isConstQualified()); } +bool TypeImplementsByteRepr(clang::QualType qt) { + if (qt->isEnumeralType()) { + return false; + } + if (qt->isIntegerType() || qt->isFloatingType()) { + return true; + } + if (const auto *arr = qt->getAsArrayTypeUnsafe()) { + return TypeImplementsByteRepr(arr->getElementType()); + } + if (const auto *rd = qt->getAsRecordDecl()) { + if (rd->isUnion()) { + return true; + } + for (const auto *field : rd->fields()) { + if (!TypeImplementsByteRepr(field->getType())) { + return false; + } + } + return true; + } + return false; +} + +bool RustSizeDivergesFromC(clang::QualType qt) { + qt = qt.getCanonicalType(); + // Records have Rc> fields that diverge from the C size + if (qt->isRecordType()) { + return true; + } + if (auto *arr = qt->getAsArrayTypeUnsafe()) { + return RustSizeDivergesFromC(arr->getElementType()); + } + return false; +} + bool IsMutatingCall(const clang::CallExpr *expr) { if (auto *callee = expr->getDirectCallee()) { if (auto *method = clang::dyn_cast(callee)) { diff --git a/cpp2rust/converter/converter_lib.h b/cpp2rust/converter/converter_lib.h index 25c84210..d652735e 100644 --- a/cpp2rust/converter/converter_lib.h +++ b/cpp2rust/converter/converter_lib.h @@ -52,6 +52,10 @@ bool IsUnsignedArithOp(const clang::BinaryOperator *expr); bool IsMut(clang::QualType qual_type); +bool TypeImplementsByteRepr(clang::QualType qt); + +bool RustSizeDivergesFromC(clang::QualType qt); + bool IsMutatingCall(const clang::CallExpr *expr); bool IsOverloadedFunction(const clang::FunctionDecl *decl); diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index eb89d496..b167b26a 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -1322,6 +1322,20 @@ bool ConverterRefCount::VisitExplicitCastExpr(clang::ExplicitCastExpr *expr) { } } +bool ConverterRefCount::VisitUnaryExprOrTypeTraitExpr( + clang::UnaryExprOrTypeTraitExpr *expr) { + if (expr->getKind() == clang::UnaryExprOrTypeTrait::UETT_SizeOf) { + auto arg_type = expr->isArgumentType() ? expr->getArgumentType() + : expr->getArgumentExpr()->getType(); + if (RustSizeDivergesFromC(arg_type)) { + StrCat(std::format("{}usize", ctx_.getTypeSize(arg_type) / 8)); + computed_expr_type_ = ComputedExprType::FreshValue; + return false; + } + } + return Converter::VisitUnaryExprOrTypeTraitExpr(expr); +} + bool ConverterRefCount::VisitStmtExpr(clang::StmtExpr *expr) { PushConversionKind push(*this, ConversionKind::FullRefCount); return Converter::VisitStmtExpr(expr); diff --git a/cpp2rust/converter/models/converter_refcount.h b/cpp2rust/converter/models/converter_refcount.h index 1a3634a3..7737a244 100644 --- a/cpp2rust/converter/models/converter_refcount.h +++ b/cpp2rust/converter/models/converter_refcount.h @@ -43,6 +43,9 @@ class ConverterRefCount final : public Converter { void AddByteReprTrait(const clang::EnumDecl *decl) override; + bool + VisitUnaryExprOrTypeTraitExpr(clang::UnaryExprOrTypeTraitExpr *expr) override; + void AddDefaultTrait(const clang::RecordDecl *decl) override; void AddDefaultTraitForUnion(const clang::RecordDecl *decl) override; From 8fa8bec3c0789d0ddbd21b11ac1f7dc1afcce18e Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 24 Jun 2026 11:34:07 +0100 Subject: [PATCH 02/15] Add byte_size in ByteRepr to capture C size --- .../converter/models/converter_refcount.cpp | 6 +- libcc2rs/src/rc.rs | 97 +++++++++++-------- libcc2rs/src/reinterpret.rs | 14 ++- 3 files changed, 69 insertions(+), 48 deletions(-) diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index b167b26a..d104e4b9 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -566,7 +566,8 @@ static bool recordImplementsByteRepr(const clang::RecordDecl *decl) { void ConverterRefCount::AddByteReprTrait(const clang::RecordDecl *decl) { auto struct_name = GetRecordName(decl); - if (!recordImplementsByteRepr(decl)) { + + if (!TypeImplementsByteRepr(ctx_.getCanonicalTagType(decl))) { StrCat(std::format("impl ByteRepr for {}", struct_name)); PushBrace brace(*this); return; @@ -577,6 +578,9 @@ void ConverterRefCount::AddByteReprTrait(const clang::RecordDecl *decl) { const auto &layout = ctx_.getASTRecordLayout(decl); + StrCat(std::format("fn byte_size() -> usize {{ {} }}", + ctx_.getTypeSize(ctx_.getCanonicalTagType(decl)) / 8)); + StrCat("fn to_bytes(&self, buf: &mut [u8])"); { PushBrace fn_brace(*this); diff --git a/libcc2rs/src/rc.rs b/libcc2rs/src/rc.rs index ccf2f991..6a643d6f 100644 --- a/libcc2rs/src/rc.rs +++ b/libcc2rs/src/rc.rs @@ -16,6 +16,13 @@ use crate::reinterpret::{ByteRepr, OriginalAlloc, SingleOriginalAlloc, SliceOrig pub type Value = Rc>; +struct ReinterpretedView { + // Pointer to the source of reinterpret + alloc: Rc, + // C++ size of the reinterpreted view + elem_byte_size: usize, +} + #[derive(Default)] enum PtrKind { #[default] @@ -25,7 +32,7 @@ enum PtrKind { HeapSingle(Weak>), HeapArray(Weak>>), Vec(Weak>>), - Reinterpreted(Rc), + Reinterpreted(Rc), } pub enum StrongPtr { @@ -59,7 +66,7 @@ impl StrongPtr { cell, } => { // Read-through: always re-read from the original allocation. - let mut buf = vec![0u8; std::mem::size_of::()]; + let mut buf = vec![0u8; T::byte_size()]; alloc.read_bytes(*byte_offset, &mut buf); *cell.borrow_mut() = Some(T::from_bytes(&buf)); Ref::map(cell.borrow(), |opt| opt.as_ref().unwrap()) @@ -77,8 +84,8 @@ impl fmt::Debug for PtrKind { PtrKind::HeapSingle(w) => write!(f, "HeapSingle({:?})", w.as_ptr()), PtrKind::StackArray(w) => write!(f, "StackArray({:?})", w.as_ptr()), PtrKind::HeapArray(w) => write!(f, "HeapArray({:?})", w.as_ptr()), - PtrKind::Reinterpreted(data) => { - write!(f, "Reinterpreted(0x{:x})", data.address()) + PtrKind::Reinterpreted(view) => { + write!(f, "Reinterpreted(0x{:x})", view.alloc.address()) } } } @@ -93,7 +100,7 @@ impl Clone for PtrKind { PtrKind::HeapSingle(weak) => PtrKind::HeapSingle(weak.clone()), PtrKind::StackArray(weak) => PtrKind::StackArray(weak.clone()), PtrKind::HeapArray(weak) => PtrKind::HeapArray(weak.clone()), - PtrKind::Reinterpreted(data) => PtrKind::Reinterpreted(Rc::clone(data)), + PtrKind::Reinterpreted(view) => PtrKind::Reinterpreted(Rc::clone(view)), } } } @@ -105,7 +112,7 @@ impl PtrKind { PtrKind::StackSingle(w) | PtrKind::HeapSingle(w) => w.as_ptr() as usize, PtrKind::Vec(w) => w.as_ptr() as usize, PtrKind::StackArray(w) | PtrKind::HeapArray(w) => w.as_ptr() as usize, - PtrKind::Reinterpreted(data) => data.address(), + PtrKind::Reinterpreted(view) => view.alloc.address(), } } } @@ -251,40 +258,40 @@ impl Ptr { #[inline] fn elem_step(&self) -> usize { match &self.kind { - PtrKind::Reinterpreted(_) => std::mem::size_of::(), + PtrKind::Reinterpreted(view) => view.elem_byte_size, _ => 1, } } #[inline] pub fn len(&self) -> usize { - match self.kind { + match &self.kind { PtrKind::Null => 0, PtrKind::StackSingle(_) | PtrKind::HeapSingle(_) => 1, - PtrKind::Vec(ref weak) => weak.upgrade().expect("ub: dangling pointer").borrow().len(), - PtrKind::StackArray(ref weak) | PtrKind::HeapArray(ref weak) => { + PtrKind::Vec(weak) => weak.upgrade().expect("ub: dangling pointer").borrow().len(), + PtrKind::StackArray(weak) | PtrKind::HeapArray(weak) => { weak.upgrade().expect("ub: dangling pointer").borrow().len() } - PtrKind::Reinterpreted(ref data) => data.total_byte_len() / std::mem::size_of::(), + PtrKind::Reinterpreted(view) => view.alloc.total_byte_len() / view.elem_byte_size, } } #[inline] pub fn is_empty(&self) -> bool { - match self.kind { + match &self.kind { PtrKind::Null => true, PtrKind::StackSingle(_) | PtrKind::HeapSingle(_) => false, - PtrKind::Vec(ref weak) => weak + PtrKind::Vec(weak) => weak .upgrade() .expect("ub: dangling pointer") .borrow() .is_empty(), - PtrKind::StackArray(ref weak) | PtrKind::HeapArray(ref weak) => weak + PtrKind::StackArray(weak) | PtrKind::HeapArray(weak) => weak .upgrade() .expect("ub: dangling pointer") .borrow() .is_empty(), - PtrKind::Reinterpreted(ref data) => self.offset >= data.total_byte_len(), + PtrKind::Reinterpreted(view) => self.offset >= view.alloc.total_byte_len(), } } @@ -339,8 +346,8 @@ impl Ptr { rc: weak.upgrade().expect("ub: dangling pointer"), offset: self.offset, }, - PtrKind::Reinterpreted(data) => StrongPtr::Reinterpreted { - alloc: Rc::clone(data), + PtrKind::Reinterpreted(view) => StrongPtr::Reinterpreted { + alloc: Rc::clone(&view.alloc), byte_offset: self.offset, cell: RefCell::new(None), }, @@ -365,10 +372,10 @@ impl Ptr { let rc = weak.upgrade().expect("ub: dangling pointer"); rc.borrow_mut()[self.offset] = value; } - PtrKind::Reinterpreted(data) => { - let mut buf = vec![0u8; std::mem::size_of::()]; + PtrKind::Reinterpreted(view) => { + let mut buf = vec![0u8; T::byte_size()]; value.to_bytes(&mut buf); - data.write_bytes(self.offset, &buf); + view.alloc.write_bytes(self.offset, &buf); } } } @@ -391,30 +398,34 @@ impl Ptr { return self_any.downcast_ref::>().unwrap().clone(); } - if std::mem::size_of::() == 0 { + if U::byte_size() == 0 { panic!("cannot reinterpret_cast to zero-sized type"); } + let src_byte_off = self.offset.wrapping_mul(T::byte_size()); let (alloc, abs_byte_off): (Rc, usize) = match &self.kind { PtrKind::Null => return Ptr::null(), PtrKind::StackSingle(weak) | PtrKind::HeapSingle(weak) => ( Rc::new(SingleOriginalAlloc { weak: weak.clone() }), - self.byte_offset(), + src_byte_off, ), PtrKind::Vec(weak) => ( Rc::new(SliceOriginalAlloc { weak: weak.clone() }), - self.byte_offset(), + src_byte_off, ), PtrKind::StackArray(weak) | PtrKind::HeapArray(weak) => ( Rc::new(SliceOriginalAlloc { weak: weak.clone() }), - self.byte_offset(), + src_byte_off, ), - PtrKind::Reinterpreted(data) => (Rc::clone(data), self.offset), + PtrKind::Reinterpreted(view) => (Rc::clone(&view.alloc), self.offset), }; Ptr { offset: abs_byte_off, - kind: PtrKind::Reinterpreted(alloc), + kind: PtrKind::Reinterpreted(Rc::new(ReinterpretedView { + alloc, + elem_byte_size: U::byte_size(), + })), } } } @@ -441,13 +452,13 @@ impl Ptr { let mut borrow = rc.borrow_mut(); f(&mut borrow[self.offset]) } - PtrKind::Reinterpreted(data) => { - let mut buf = vec![0u8; std::mem::size_of::()]; - data.read_bytes(self.offset, &mut buf); + PtrKind::Reinterpreted(view) => { + let mut buf = vec![0u8; T::byte_size()]; + view.alloc.read_bytes(self.offset, &mut buf); let mut val = T::from_bytes(&buf); let ret = f(&mut val); val.to_bytes(&mut buf); - data.write_bytes(self.offset, &buf); + view.alloc.write_bytes(self.offset, &buf); ret } } @@ -474,9 +485,9 @@ impl Ptr { let borrow = rc.borrow(); f(&borrow[self.offset]) } - PtrKind::Reinterpreted(data) => { - let mut buf = vec![0u8; std::mem::size_of::()]; - data.read_bytes(self.offset, &mut buf); + PtrKind::Reinterpreted(view) => { + let mut buf = vec![0u8; T::byte_size()]; + view.alloc.read_bytes(self.offset, &mut buf); let val = T::from_bytes(&buf); f(&val) } @@ -501,9 +512,9 @@ impl Ptr { PtrKind::StackArray(ref weak) | PtrKind::HeapArray(ref weak) => { weak.upgrade().expect("ub: dangling pointer").borrow()[self.offset].clone() } - PtrKind::Reinterpreted(ref data) => { - let mut buf = vec![0u8; std::mem::size_of::()]; - data.read_bytes(self.offset, &mut buf); + PtrKind::Reinterpreted(ref view) => { + let mut buf = vec![0u8; T::byte_size()]; + view.alloc.read_bytes(self.offset, &mut buf); T::from_bytes(&buf) } } @@ -535,7 +546,7 @@ impl Ptr { let strong = weak.upgrade().expect("ub: dangling pointer"); (*strong.borrow_mut())[self.get_offset()..last].sort(); } - PtrKind::Reinterpreted(..) => { + PtrKind::Reinterpreted(_) => { panic!("sorting not supported for reinterpreted pointers") } } @@ -580,7 +591,7 @@ impl Ptr { let mut borrow = strong.borrow_mut(); sort(&mut borrow, self.get_offset(), last, &mut cmp); } - PtrKind::Reinterpreted(..) => { + PtrKind::Reinterpreted(_) => { panic!("sorting not supported for reinterpreted pointers") } } @@ -856,7 +867,7 @@ impl ToOwnedOption for Ptr { } PtrKind::Vec(_) => panic!("Can't own a vector"), PtrKind::HeapArray(_) => panic!("Can't own an array variable as single"), - PtrKind::Reinterpreted(..) => panic!("Can't own a reinterpreted pointer"), + PtrKind::Reinterpreted(_) => panic!("Can't own a reinterpreted pointer"), } } } @@ -882,7 +893,7 @@ impl ToOwnedOption> for Ptr { } PtrKind::Vec(_) => panic!("Can't own a vector"), PtrKind::HeapSingle(_) => panic!("Can't own a single variable as an array"), - PtrKind::Reinterpreted(..) => panic!("Can't own a reinterpreted pointer"), + PtrKind::Reinterpreted(_) => panic!("Can't own a reinterpreted pointer"), } } } @@ -898,7 +909,7 @@ impl fmt::Debug for Ptr { (Weak::as_ptr(w) as usize).wrapping_add(self.byte_offset()) } PtrKind::Vec(w) => (Weak::as_ptr(w) as usize).wrapping_add(self.byte_offset()), - PtrKind::Reinterpreted(data) => data.address().wrapping_add(self.byte_offset()), + PtrKind::Reinterpreted(view) => view.alloc.address().wrapping_add(self.byte_offset()), }; write!(f, "0x{:x}", addr) } @@ -994,9 +1005,9 @@ impl Ptr { let raw = strong.borrow(); raw[start..end].to_vec() } - PtrKind::Reinterpreted(ref data) => { + PtrKind::Reinterpreted(ref view) => { let mut buf = vec![0u8; end.wrapping_sub(start)]; - data.read_bytes(start, &mut buf); + view.alloc.read_bytes(start, &mut buf); buf } } diff --git a/libcc2rs/src/reinterpret.rs b/libcc2rs/src/reinterpret.rs index 452b35de..c554814f 100644 --- a/libcc2rs/src/reinterpret.rs +++ b/libcc2rs/src/reinterpret.rs @@ -4,6 +4,12 @@ use std::{cell::RefCell, rc::Weak}; pub trait ByteRepr: 'static { + fn byte_size() -> usize + where + Self: Sized, + { + std::mem::size_of::() + } fn to_bytes(&self, _buf: &mut [u8]) { panic!("ByteRepr not supported for this type"); } @@ -83,7 +89,7 @@ pub trait OriginalAlloc { // Only serializes the overlapping elements, not the whole slice. fn slice_read_bytes(slice: &[S], byte_offset: usize, buf: &mut [u8]) { let len = buf.len(); - let elem_size = std::mem::size_of::(); + let elem_size = S::byte_size(); let first_elem = byte_offset / elem_size; let last_elem = (byte_offset + len).div_ceil(elem_size); let tmp_len = (last_elem - first_elem) * elem_size; @@ -98,7 +104,7 @@ fn slice_read_bytes(slice: &[S], byte_offset: usize, buf: &mut [u8] // Write `data` at `byte_offset` into a slice of S elements. // Only deserializes/reserializes the overlapping elements. fn slice_write_bytes(slice: &mut [S], byte_offset: usize, data: &[u8]) { - let elem_size = std::mem::size_of::(); + let elem_size = S::byte_size(); let mut elem_buf = vec![0u8; elem_size]; let first_elem = byte_offset / elem_size; let num_elem = data.len().div_ceil(elem_size); @@ -136,7 +142,7 @@ impl OriginalAlloc for SingleOriginalAlloc { } fn total_byte_len(&self) -> usize { - std::mem::size_of::() + T::byte_size() } fn address(&self) -> usize { @@ -190,7 +196,7 @@ impl OriginalAlloc for SliceOriginalAlloc { fn total_byte_len(&self) -> usize { let rc = self.weak.upgrade().expect("ub: dangling pointer"); let val = rc.borrow(); - std::mem::size_of_val(val.as_slice()) + val.as_slice().len() * ::byte_size() } fn address(&self) -> usize { From a07a40fbc050743d06c68de5a60f7113a6142b4a Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 25 Jun 2026 15:06:31 +0100 Subject: [PATCH 03/15] Delete unused function --- .../converter/models/converter_refcount.cpp | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index d104e4b9..3b142ca2 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -545,28 +545,9 @@ void ConverterRefCount::AddDropTrait(const clang::CXXRecordDecl *decl) { StrCat('}'); } -static bool recordImplementsByteRepr(const clang::RecordDecl *decl) { - if (decl->isUnion()) { - return false; - } - - // ByteRepr is only supported for user-defined structs that contain ByteRepr - // fields. - for (auto *f : decl->fields()) { - auto qt = f->getType(); - if (!qt->isIntegerType() && !qt->isFloatingType() && - !qt->isEnumeralType()) { - return false; - } - } - - return true; -} - void ConverterRefCount::AddByteReprTrait(const clang::RecordDecl *decl) { auto struct_name = GetRecordName(decl); - if (!TypeImplementsByteRepr(ctx_.getCanonicalTagType(decl))) { StrCat(std::format("impl ByteRepr for {}", struct_name)); PushBrace brace(*this); From 7db50020b618fdff2b9b1a6a4cae91db10b91f35 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 25 Jun 2026 15:06:55 +0100 Subject: [PATCH 04/15] Add correct from_bytes type --- cpp2rust/converter/models/converter_refcount.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index 3b142ca2..fa484685 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -585,9 +585,12 @@ void ConverterRefCount::AddByteReprTrait(const clang::RecordDecl *decl) { for (auto *field : decl->fields()) { auto byte_off = layout.getFieldOffset(idx) / 8; auto byte_size = ctx_.getTypeSize(field->getType()) / 8; + PushConversionKind push(*this, ConversionKind::FullRefCount); + std::string storage_ty = ToString(field->getType()); + Unwrap(storage_ty, "Value<", ">"); StrCat(std::format( "{}: Rc::new(RefCell::new(<{}>::from_bytes(&buf[{}..{}]))),", - GetNamedDeclAsString(field), Mapper::Map(field->getType()), byte_off, + GetNamedDeclAsString(field), storage_ty, byte_off, byte_off + byte_size)); ++idx; } From c66a712327ddb386baea49e68099049c2162e017 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 25 Jun 2026 15:07:43 +0100 Subject: [PATCH 05/15] Update tests --- .../out/refcount/cross_tu_tag_collision.rs | 3 + tests/unit/out/refcount/addr_of_global.rs | 3 + tests/unit/out/refcount/anonymous-struct.rs | 61 ++++++++++++++++++- tests/unit/out/refcount/anonymous-struct_c.rs | 61 ++++++++++++++++++- tests/unit/out/refcount/anonymous_enum.rs | 56 ++--------------- tests/unit/out/refcount/anonymous_enum_c.rs | 56 ++--------------- tests/unit/out/refcount/array_const_init.rs | 18 +++++- .../out/refcount/array_of_noncopy_struct.rs | 16 ++++- tests/unit/out/refcount/bounded_struct_ptr.rs | 3 + tests/unit/out/refcount/c_struct.rs | 30 ++++++--- tests/unit/out/refcount/class.rs | 19 +++++- tests/unit/out/refcount/class_templates.rs | 42 ++++++++++++- tests/unit/out/refcount/clone_vs_move.rs | 3 + tests/unit/out/refcount/complex_function.rs | 3 + tests/unit/out/refcount/exprs.rs | 3 + tests/unit/out/refcount/fft.rs | 3 + tests/unit/out/refcount/fn_ptr_stable_sort.rs | 3 + .../refcount/foreach_disjoint_field_borrow.rs | 16 ++++- .../unit/out/refcount/function_overloading.rs | 3 + .../refcount/global_without_initializer.rs | 3 + .../out/refcount/goto_aggregate_default.rs | 3 + tests/unit/out/refcount/huffman.rs | 26 +++++++- .../refcount/immutable-deref-on-func-call.rs | 3 + tests/unit/out/refcount/implicit_autoref.rs | 14 ++++- tests/unit/out/refcount/init.rs | 3 + tests/unit/out/refcount/kruskal.rs | 45 +++++++++++++- .../refcount/local_anon_struct_collision.rs | 6 ++ .../unit/out/refcount/memcpy_struct_struct.rs | 7 ++- tests/unit/out/refcount/nested_structs.rs | 18 ++++++ tests/unit/out/refcount/new_struct.rs | 3 + tests/unit/out/refcount/operator_less_than.rs | 3 + tests/unit/out/refcount/pod.rs | 3 + tests/unit/out/refcount/pointers.rs | 3 + tests/unit/out/refcount/polymorphism.rs | 6 ++ tests/unit/out/refcount/push_emplace_back.rs | 21 ++++++- tests/unit/out/refcount/random.rs | 3 + .../out/refcount/reinterpret_cast_struct.rs | 3 + .../reinterpret_cast_struct_to_struct.rs | 6 ++ tests/unit/out/refcount/reserved_keywords.rs | 3 + .../unit/out/refcount/static_var_in_class.rs | 6 ++ tests/unit/out/refcount/struct_ctor.rs | 3 + tests/unit/out/refcount/struct_ptr.rs | 3 + .../unit/out/refcount/typedef-anon-struct.rs | 17 +++++- tests/unit/out/refcount/unique_ptr.rs | 17 +++++- .../out/refcount/unique_ptr_const_deref.rs | 14 ++++- tests/unit/out/refcount/unique_ptr_nested.rs | 17 +++++- tests/unit/out/refcount/unique_ptr_struct.rs | 3 + tests/unit/out/refcount/va_arg_struct_ctx.rs | 3 + tests/unit/out/refcount/void_cast.rs | 17 +++++- 49 files changed, 547 insertions(+), 137 deletions(-) diff --git a/tests/multi-file/cross_tu_tag_collision/out/refcount/cross_tu_tag_collision.rs b/tests/multi-file/cross_tu_tag_collision/out/refcount/cross_tu_tag_collision.rs index 90529368..981fa9ae 100644 --- a/tests/multi-file/cross_tu_tag_collision/out/refcount/cross_tu_tag_collision.rs +++ b/tests/multi-file/cross_tu_tag_collision/out/refcount/cross_tu_tag_collision.rs @@ -11,6 +11,9 @@ pub struct widget { pub id: Value, } impl ByteRepr for widget { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.id.borrow()).to_bytes(&mut buf[0..4]); } diff --git a/tests/unit/out/refcount/addr_of_global.rs b/tests/unit/out/refcount/addr_of_global.rs index 01ddb7f7..0d03ca3b 100644 --- a/tests/unit/out/refcount/addr_of_global.rs +++ b/tests/unit/out/refcount/addr_of_global.rs @@ -19,6 +19,9 @@ impl Clone for Inner { } } impl ByteRepr for Inner { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.value.borrow()).to_bytes(&mut buf[0..4]); } diff --git a/tests/unit/out/refcount/anonymous-struct.rs b/tests/unit/out/refcount/anonymous-struct.rs index fcd7db80..ad257c16 100644 --- a/tests/unit/out/refcount/anonymous-struct.rs +++ b/tests/unit/out/refcount/anonymous-struct.rs @@ -21,6 +21,9 @@ impl Clone for Outer_Named { } } impl ByteRepr for Outer_Named { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.a.borrow()).to_bytes(&mut buf[0..4]); (*self.b.borrow()).to_bytes(&mut buf[4..8]); @@ -47,6 +50,9 @@ impl Clone for anon_0 { } } impl ByteRepr for anon_0 { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.c.borrow()).to_bytes(&mut buf[0..4]); (*self.d.borrow()).to_bytes(&mut buf[4..8]); @@ -73,6 +79,9 @@ impl Clone for anon_1 { } } impl ByteRepr for anon_1 { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.g.borrow()).to_bytes(&mut buf[0..4]); (*self.h.borrow()).to_bytes(&mut buf[4..8]); @@ -99,6 +108,9 @@ impl Clone for anon_2 { } } impl ByteRepr for anon_2 { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.e.borrow()).to_bytes(&mut buf[0..4]); (*self.f.borrow()).to_bytes(&mut buf[4..8]); @@ -123,6 +135,9 @@ impl Clone for anon_4 { } } impl ByteRepr for anon_4 { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.j.borrow()).to_bytes(&mut buf[0..4]); } @@ -145,6 +160,9 @@ impl Clone for anon_5 { } } impl ByteRepr for anon_5 { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.k.borrow()).to_bytes(&mut buf[0..4]); } @@ -170,7 +188,23 @@ impl Clone for anon_3 { this } } -impl ByteRepr for anon_3 {} +impl ByteRepr for anon_3 { + fn byte_size() -> usize { + 12 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.i.borrow()).to_bytes(&mut buf[0..4]); + (*self.inner_named.borrow()).to_bytes(&mut buf[4..8]); + (*self.anon_5.borrow()).to_bytes(&mut buf[8..12]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + i: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + inner_named: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + anon_5: Rc::new(RefCell::new(::from_bytes(&buf[8..12]))), + } + } +} #[derive(Default)] pub struct Outer { pub named: Value, @@ -191,7 +225,27 @@ impl Clone for Outer { this } } -impl ByteRepr for Outer {} +impl ByteRepr for Outer { + fn byte_size() -> usize { + 44 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.named.borrow()).to_bytes(&mut buf[0..8]); + (*self.anonymous_named_0.borrow()).to_bytes(&mut buf[8..16]); + (*self.anonymous_named_1.borrow()).to_bytes(&mut buf[16..24]); + (*self.anon_2.borrow()).to_bytes(&mut buf[24..32]); + (*self.anon_3.borrow()).to_bytes(&mut buf[32..44]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + named: Rc::new(RefCell::new(::from_bytes(&buf[0..8]))), + anonymous_named_0: Rc::new(RefCell::new(::from_bytes(&buf[8..16]))), + anonymous_named_1: Rc::new(RefCell::new(::from_bytes(&buf[16..24]))), + anon_2: Rc::new(RefCell::new(::from_bytes(&buf[24..32]))), + anon_3: Rc::new(RefCell::new(::from_bytes(&buf[32..44]))), + } + } +} pub fn main() { std::process::exit(main_0()); } @@ -274,6 +328,9 @@ fn main_0() -> i32 { } } impl ByteRepr for anon_6 { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); (*self.z.borrow()).to_bytes(&mut buf[4..8]); diff --git a/tests/unit/out/refcount/anonymous-struct_c.rs b/tests/unit/out/refcount/anonymous-struct_c.rs index 23ce8df8..970d6e99 100644 --- a/tests/unit/out/refcount/anonymous-struct_c.rs +++ b/tests/unit/out/refcount/anonymous-struct_c.rs @@ -12,6 +12,9 @@ pub struct Named { pub b: Value, } impl ByteRepr for Named { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.a.borrow()).to_bytes(&mut buf[0..4]); (*self.b.borrow()).to_bytes(&mut buf[4..8]); @@ -29,6 +32,9 @@ pub struct anon_0 { pub d: Value, } impl ByteRepr for anon_0 { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.c.borrow()).to_bytes(&mut buf[0..4]); (*self.d.borrow()).to_bytes(&mut buf[4..8]); @@ -46,6 +52,9 @@ pub struct anon_1 { pub h: Value, } impl ByteRepr for anon_1 { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.g.borrow()).to_bytes(&mut buf[0..4]); (*self.h.borrow()).to_bytes(&mut buf[4..8]); @@ -63,6 +72,9 @@ pub struct anon_2 { pub f: Value, } impl ByteRepr for anon_2 { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.e.borrow()).to_bytes(&mut buf[0..4]); (*self.f.borrow()).to_bytes(&mut buf[4..8]); @@ -79,6 +91,9 @@ pub struct anon_4 { pub j: Value, } impl ByteRepr for anon_4 { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.j.borrow()).to_bytes(&mut buf[0..4]); } @@ -93,6 +108,9 @@ pub struct anon_5 { pub k: Value, } impl ByteRepr for anon_5 { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.k.borrow()).to_bytes(&mut buf[0..4]); } @@ -108,7 +126,23 @@ pub struct anon_3 { pub inner_named: Value, pub anon_5: Value, } -impl ByteRepr for anon_3 {} +impl ByteRepr for anon_3 { + fn byte_size() -> usize { + 12 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.i.borrow()).to_bytes(&mut buf[0..4]); + (*self.inner_named.borrow()).to_bytes(&mut buf[4..8]); + (*self.anon_5.borrow()).to_bytes(&mut buf[8..12]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + i: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + inner_named: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + anon_5: Rc::new(RefCell::new(::from_bytes(&buf[8..12]))), + } + } +} #[derive(Default)] pub struct Outer { pub named: Value, @@ -117,7 +151,27 @@ pub struct Outer { pub anon_2: Value, pub anon_3: Value, } -impl ByteRepr for Outer {} +impl ByteRepr for Outer { + fn byte_size() -> usize { + 44 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.named.borrow()).to_bytes(&mut buf[0..8]); + (*self.anon0.borrow()).to_bytes(&mut buf[8..16]); + (*self.anon1.borrow()).to_bytes(&mut buf[16..24]); + (*self.anon_2.borrow()).to_bytes(&mut buf[24..32]); + (*self.anon_3.borrow()).to_bytes(&mut buf[32..44]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + named: Rc::new(RefCell::new(::from_bytes(&buf[0..8]))), + anon0: Rc::new(RefCell::new(::from_bytes(&buf[8..16]))), + anon1: Rc::new(RefCell::new(::from_bytes(&buf[16..24]))), + anon_2: Rc::new(RefCell::new(::from_bytes(&buf[24..32]))), + anon_3: Rc::new(RefCell::new(::from_bytes(&buf[32..44]))), + } + } +} pub fn main() { std::process::exit(main_0()); } @@ -176,6 +230,9 @@ fn main_0() -> i32 { pub z: Value, } impl ByteRepr for anon_6 { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); (*self.z.borrow()).to_bytes(&mut buf[4..8]); diff --git a/tests/unit/out/refcount/anonymous_enum.rs b/tests/unit/out/refcount/anonymous_enum.rs index 9fbf91ed..f63deffd 100644 --- a/tests/unit/out/refcount/anonymous_enum.rs +++ b/tests/unit/out/refcount/anonymous_enum.rs @@ -22,14 +22,6 @@ impl From for anon_0 { } } libcc2rs::impl_enum_inc_dec!(anon_0); -impl ByteRepr for anon_0 { - fn to_bytes(&self, buf: &mut [u8]) { - (*self as i32).to_bytes(buf); - } - fn from_bytes(buf: &[u8]) -> Self { - ::from(i32::from_bytes(buf)) - } -} #[derive(Clone, Copy, PartialEq, Debug, Default)] enum anon_1 { #[default] @@ -46,14 +38,6 @@ impl From for anon_1 { } } libcc2rs::impl_enum_inc_dec!(anon_1); -impl ByteRepr for anon_1 { - fn to_bytes(&self, buf: &mut [u8]) { - (*self as i32).to_bytes(buf); - } - fn from_bytes(buf: &[u8]) -> Self { - ::from(i32::from_bytes(buf)) - } -} #[derive(Default)] pub struct S { pub a: Value, @@ -67,6 +51,9 @@ impl Clone for S { } } impl ByteRepr for S { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.a.borrow()).to_bytes(&mut buf[0..4]); } @@ -92,14 +79,6 @@ impl From for TdEnum { } } libcc2rs::impl_enum_inc_dec!(TdEnum); -impl ByteRepr for TdEnum { - fn to_bytes(&self, buf: &mut [u8]) { - (*self as i32).to_bytes(buf); - } - fn from_bytes(buf: &[u8]) -> Self { - ::from(i32::from_bytes(buf)) - } -} #[derive(Clone, Copy, PartialEq, Debug, Default)] enum anon_2 { #[default] @@ -116,14 +95,6 @@ impl From for anon_2 { } } libcc2rs::impl_enum_inc_dec!(anon_2); -impl ByteRepr for anon_2 { - fn to_bytes(&self, buf: &mut [u8]) { - (*self as i32).to_bytes(buf); - } - fn from_bytes(buf: &[u8]) -> Self { - ::from(i32::from_bytes(buf)) - } -} #[derive(Default)] pub struct WithAnonField { pub a: Value, @@ -138,18 +109,7 @@ impl Clone for WithAnonField { this } } -impl ByteRepr for WithAnonField { - fn to_bytes(&self, buf: &mut [u8]) { - (*self.a.borrow()).to_bytes(&mut buf[0..4]); - (*self.field.borrow()).to_bytes(&mut buf[4..8]); - } - fn from_bytes(buf: &[u8]) -> Self { - Self { - a: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), - field: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), - } - } -} +impl ByteRepr for WithAnonField {} pub fn main() { std::process::exit(main_0()); } @@ -170,14 +130,6 @@ fn main_0() -> i32 { } } libcc2rs::impl_enum_inc_dec!(anon_3); - impl ByteRepr for anon_3 { - fn to_bytes(&self, buf: &mut [u8]) { - (*self as i32).to_bytes(buf); - } - fn from_bytes(buf: &[u8]) -> Self { - ::from(i32::from_bytes(buf)) - } - }; assert!(((anon_0::FIRST_A as i32) != (anon_0::FIRST_B as i32))); assert!(((anon_1::SECOND_A as i32) != (anon_1::SECOND_B as i32))); assert!(((anon_3::THIRD_A as i32) != (anon_3::THIRD_B as i32))); diff --git a/tests/unit/out/refcount/anonymous_enum_c.rs b/tests/unit/out/refcount/anonymous_enum_c.rs index 199dc233..43dc943b 100644 --- a/tests/unit/out/refcount/anonymous_enum_c.rs +++ b/tests/unit/out/refcount/anonymous_enum_c.rs @@ -22,14 +22,6 @@ impl From for anon_0 { } } libcc2rs::impl_enum_inc_dec!(anon_0); -impl ByteRepr for anon_0 { - fn to_bytes(&self, buf: &mut [u8]) { - (*self as i32).to_bytes(buf); - } - fn from_bytes(buf: &[u8]) -> Self { - ::from(i32::from_bytes(buf)) - } -} #[derive(Clone, Copy, PartialEq, Debug, Default)] enum anon_1 { #[default] @@ -46,19 +38,14 @@ impl From for anon_1 { } } libcc2rs::impl_enum_inc_dec!(anon_1); -impl ByteRepr for anon_1 { - fn to_bytes(&self, buf: &mut [u8]) { - (*self as i32).to_bytes(buf); - } - fn from_bytes(buf: &[u8]) -> Self { - ::from(i32::from_bytes(buf)) - } -} #[derive(Default)] pub struct S { pub a: Value, } impl ByteRepr for S { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.a.borrow()).to_bytes(&mut buf[0..4]); } @@ -84,14 +71,6 @@ impl From for TdEnum_enum { } } libcc2rs::impl_enum_inc_dec!(TdEnum_enum); -impl ByteRepr for TdEnum_enum { - fn to_bytes(&self, buf: &mut [u8]) { - (*self as i32).to_bytes(buf); - } - fn from_bytes(buf: &[u8]) -> Self { - ::from(i32::from_bytes(buf)) - } -} #[derive(Clone, Copy, PartialEq, Debug, Default)] enum anon_2 { #[default] @@ -108,31 +87,12 @@ impl From for anon_2 { } } libcc2rs::impl_enum_inc_dec!(anon_2); -impl ByteRepr for anon_2 { - fn to_bytes(&self, buf: &mut [u8]) { - (*self as i32).to_bytes(buf); - } - fn from_bytes(buf: &[u8]) -> Self { - ::from(i32::from_bytes(buf)) - } -} #[derive(Default)] pub struct WithAnonField { pub a: Value, pub field: Value, } -impl ByteRepr for WithAnonField { - fn to_bytes(&self, buf: &mut [u8]) { - (*self.a.borrow()).to_bytes(&mut buf[0..4]); - (*self.field.borrow()).to_bytes(&mut buf[4..8]); - } - fn from_bytes(buf: &[u8]) -> Self { - Self { - a: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), - field: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), - } - } -} +impl ByteRepr for WithAnonField {} pub fn main() { std::process::exit(main_0()); } @@ -153,14 +113,6 @@ fn main_0() -> i32 { } } libcc2rs::impl_enum_inc_dec!(anon_3); - impl ByteRepr for anon_3 { - fn to_bytes(&self, buf: &mut [u8]) { - (*self as i32).to_bytes(buf); - } - fn from_bytes(buf: &[u8]) -> Self { - ::from(i32::from_bytes(buf)) - } - }; assert!(((((anon_0::FIRST_A as i32) != (anon_0::FIRST_B as i32)) as i32) != 0)); assert!(((((anon_1::SECOND_A as i32) != (anon_1::SECOND_B as i32)) as i32) != 0)); assert!(((((anon_3::THIRD_A as i32) != (anon_3::THIRD_B as i32)) as i32) != 0)); diff --git a/tests/unit/out/refcount/array_const_init.rs b/tests/unit/out/refcount/array_const_init.rs index 784f3a73..7a2cf78d 100644 --- a/tests/unit/out/refcount/array_const_init.rs +++ b/tests/unit/out/refcount/array_const_init.rs @@ -25,7 +25,23 @@ impl Default for S { } } } -impl ByteRepr for S {} +impl ByteRepr for S { + fn byte_size() -> usize { + 20 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.head.borrow()).to_bytes(&mut buf[0..4]); + (*self.tail.borrow()).to_bytes(&mut buf[4..16]); + (*self.buf.borrow()).to_bytes(&mut buf[16..20]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + head: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + tail: Rc::new(RefCell::new(>::from_bytes(&buf[4..16]))), + buf: Rc::new(RefCell::new(>::from_bytes(&buf[16..20]))), + } + } +} thread_local!( pub static s_0: Value = Rc::new(RefCell::new(S { head: Rc::new(RefCell::new(5)), diff --git a/tests/unit/out/refcount/array_of_noncopy_struct.rs b/tests/unit/out/refcount/array_of_noncopy_struct.rs index 4af56349..0c91af6d 100644 --- a/tests/unit/out/refcount/array_of_noncopy_struct.rs +++ b/tests/unit/out/refcount/array_of_noncopy_struct.rs @@ -20,7 +20,21 @@ impl Clone for NonCopy { this } } -impl ByteRepr for NonCopy {} +impl ByteRepr for NonCopy { + fn byte_size() -> usize { + 32 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.data.borrow()).to_bytes(&mut buf[0..24]); + (*self.tag.borrow()).to_bytes(&mut buf[24..28]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + data: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), + tag: Rc::new(RefCell::new(::from_bytes(&buf[24..28]))), + } + } +} pub fn main() { std::process::exit(main_0()); } diff --git a/tests/unit/out/refcount/bounded_struct_ptr.rs b/tests/unit/out/refcount/bounded_struct_ptr.rs index 477a71a6..6da5e2fb 100644 --- a/tests/unit/out/refcount/bounded_struct_ptr.rs +++ b/tests/unit/out/refcount/bounded_struct_ptr.rs @@ -21,6 +21,9 @@ impl Clone for Foo { } } impl ByteRepr for Foo { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x1.borrow()).to_bytes(&mut buf[0..4]); (*self.x2.borrow()).to_bytes(&mut buf[4..8]); diff --git a/tests/unit/out/refcount/c_struct.rs b/tests/unit/out/refcount/c_struct.rs index 36ebdeb4..a0985ec8 100644 --- a/tests/unit/out/refcount/c_struct.rs +++ b/tests/unit/out/refcount/c_struct.rs @@ -12,6 +12,9 @@ pub struct Point { pub y: Value, } impl ByteRepr for Point { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); (*self.y.borrow()).to_bytes(&mut buf[4..8]); @@ -28,7 +31,21 @@ pub struct Line { pub start: Value, pub end: Value, } -impl ByteRepr for Line {} +impl ByteRepr for Line { + fn byte_size() -> usize { + 16 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.start.borrow()).to_bytes(&mut buf[0..8]); + (*self.end.borrow()).to_bytes(&mut buf[8..16]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + start: Rc::new(RefCell::new(::from_bytes(&buf[0..8]))), + end: Rc::new(RefCell::new(::from_bytes(&buf[8..16]))), + } + } +} #[derive(Default)] pub struct Node { pub value: Value, @@ -53,20 +70,15 @@ impl From for Color { } } libcc2rs::impl_enum_inc_dec!(Color); -impl ByteRepr for Color { - fn to_bytes(&self, buf: &mut [u8]) { - (*self as i32).to_bytes(buf); - } - fn from_bytes(buf: &[u8]) -> Self { - ::from(i32::from_bytes(buf)) - } -} #[derive(Default)] pub struct Inner { pub a: Value, pub b: Value, } impl ByteRepr for Inner { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.a.borrow()).to_bytes(&mut buf[0..4]); (*self.b.borrow()).to_bytes(&mut buf[4..8]); diff --git a/tests/unit/out/refcount/class.rs b/tests/unit/out/refcount/class.rs index a0c1f970..ff1c3cf4 100644 --- a/tests/unit/out/refcount/class.rs +++ b/tests/unit/out/refcount/class.rs @@ -54,6 +54,9 @@ impl Clone for Pair { } } impl ByteRepr for Pair { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.first.borrow()).to_bytes(&mut buf[0..4]); (*self.second.borrow()).to_bytes(&mut buf[4..8]); @@ -87,7 +90,21 @@ impl Clone for Route { this } } -impl ByteRepr for Route {} +impl ByteRepr for Route { + fn byte_size() -> usize { + 16 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.path.borrow()).to_bytes(&mut buf[0..8]); + (*self.cost.borrow()).to_bytes(&mut buf[8..16]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + path: Rc::new(RefCell::new(::from_bytes(&buf[0..8]))), + cost: Rc::new(RefCell::new(::from_bytes(&buf[8..16]))), + } + } +} pub fn RandomRoute_0(route: Ptr) -> i32 { if (((*(*(*route.upgrade().deref()).path.borrow()).first.borrow()) % 2) != 0) { return ({ diff --git a/tests/unit/out/refcount/class_templates.rs b/tests/unit/out/refcount/class_templates.rs index 3cbce86e..183fbd41 100644 --- a/tests/unit/out/refcount/class_templates.rs +++ b/tests/unit/out/refcount/class_templates.rs @@ -42,7 +42,19 @@ impl Clone for MyContainer_int_ { this } } -impl ByteRepr for MyContainer_int_ {} +impl ByteRepr for MyContainer_int_ { + fn byte_size() -> usize { + 24 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.vec_.borrow()).to_bytes(&mut buf[0..24]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + vec_: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), + } + } +} #[derive(Default)] pub struct MyContainer_char_ { vec_: Value>, @@ -79,7 +91,19 @@ impl Clone for MyContainer_char_ { this } } -impl ByteRepr for MyContainer_char_ {} +impl ByteRepr for MyContainer_char_ { + fn byte_size() -> usize { + 24 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.vec_.borrow()).to_bytes(&mut buf[0..24]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + vec_: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), + } + } +} #[derive(Default)] pub struct MyContainer_float_ { vec_: Value>, @@ -116,7 +140,19 @@ impl Clone for MyContainer_float_ { this } } -impl ByteRepr for MyContainer_float_ {} +impl ByteRepr for MyContainer_float_ { + fn byte_size() -> usize { + 24 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.vec_.borrow()).to_bytes(&mut buf[0..24]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + vec_: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), + } + } +} pub fn main() { std::process::exit(main_0()); } diff --git a/tests/unit/out/refcount/clone_vs_move.rs b/tests/unit/out/refcount/clone_vs_move.rs index 9f6ee411..1953e3d9 100644 --- a/tests/unit/out/refcount/clone_vs_move.rs +++ b/tests/unit/out/refcount/clone_vs_move.rs @@ -19,6 +19,9 @@ impl Clone for Bar { } } impl ByteRepr for Bar { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.w.borrow()).to_bytes(&mut buf[0..4]); } diff --git a/tests/unit/out/refcount/complex_function.rs b/tests/unit/out/refcount/complex_function.rs index 861fee9f..737edc12 100644 --- a/tests/unit/out/refcount/complex_function.rs +++ b/tests/unit/out/refcount/complex_function.rs @@ -30,6 +30,9 @@ impl Clone for X1 { } } impl ByteRepr for X1 { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.v.borrow()).to_bytes(&mut buf[0..4]); } diff --git a/tests/unit/out/refcount/exprs.rs b/tests/unit/out/refcount/exprs.rs index 6a4a1646..e8a9eed6 100644 --- a/tests/unit/out/refcount/exprs.rs +++ b/tests/unit/out/refcount/exprs.rs @@ -19,6 +19,9 @@ impl Clone for X { } } impl ByteRepr for X { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); } diff --git a/tests/unit/out/refcount/fft.rs b/tests/unit/out/refcount/fft.rs index 55e71cd7..12551ddb 100644 --- a/tests/unit/out/refcount/fft.rs +++ b/tests/unit/out/refcount/fft.rs @@ -21,6 +21,9 @@ impl Clone for Complex { } } impl ByteRepr for Complex { + fn byte_size() -> usize { + 16 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.re.borrow()).to_bytes(&mut buf[0..8]); (*self.img.borrow()).to_bytes(&mut buf[8..16]); diff --git a/tests/unit/out/refcount/fn_ptr_stable_sort.rs b/tests/unit/out/refcount/fn_ptr_stable_sort.rs index 5182170f..da7b2e8a 100644 --- a/tests/unit/out/refcount/fn_ptr_stable_sort.rs +++ b/tests/unit/out/refcount/fn_ptr_stable_sort.rs @@ -21,6 +21,9 @@ impl Clone for Item { } } impl ByteRepr for Item { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.key.borrow()).to_bytes(&mut buf[0..4]); (*self.value.borrow()).to_bytes(&mut buf[4..8]); diff --git a/tests/unit/out/refcount/foreach_disjoint_field_borrow.rs b/tests/unit/out/refcount/foreach_disjoint_field_borrow.rs index 66c9e892..57c56051 100644 --- a/tests/unit/out/refcount/foreach_disjoint_field_borrow.rs +++ b/tests/unit/out/refcount/foreach_disjoint_field_borrow.rs @@ -20,7 +20,21 @@ impl Clone for S { this } } -impl ByteRepr for S {} +impl ByteRepr for S { + fn byte_size() -> usize { + 32 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.v.borrow()).to_bytes(&mut buf[0..24]); + (*self.a.borrow()).to_bytes(&mut buf[24..28]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + v: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), + a: Rc::new(RefCell::new(::from_bytes(&buf[24..28]))), + } + } +} pub fn main() { std::process::exit(main_0()); } diff --git a/tests/unit/out/refcount/function_overloading.rs b/tests/unit/out/refcount/function_overloading.rs index 7110cd08..4e39bf8f 100644 --- a/tests/unit/out/refcount/function_overloading.rs +++ b/tests/unit/out/refcount/function_overloading.rs @@ -63,6 +63,9 @@ impl Clone for Foo { } } impl ByteRepr for Foo { + fn byte_size() -> usize { + 1 + } fn to_bytes(&self, buf: &mut [u8]) {} fn from_bytes(buf: &[u8]) -> Self { Self {} diff --git a/tests/unit/out/refcount/global_without_initializer.rs b/tests/unit/out/refcount/global_without_initializer.rs index 51fce351..f1dd9e2a 100644 --- a/tests/unit/out/refcount/global_without_initializer.rs +++ b/tests/unit/out/refcount/global_without_initializer.rs @@ -19,6 +19,9 @@ impl Clone for S { } } impl ByteRepr for S { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.a.borrow()).to_bytes(&mut buf[0..4]); } diff --git a/tests/unit/out/refcount/goto_aggregate_default.rs b/tests/unit/out/refcount/goto_aggregate_default.rs index 1043512f..c2c6d4d4 100644 --- a/tests/unit/out/refcount/goto_aggregate_default.rs +++ b/tests/unit/out/refcount/goto_aggregate_default.rs @@ -12,6 +12,9 @@ pub struct Point { pub y: Value, } impl ByteRepr for Point { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); (*self.y.borrow()).to_bytes(&mut buf[4..8]); diff --git a/tests/unit/out/refcount/huffman.rs b/tests/unit/out/refcount/huffman.rs index f320d46a..c36e85e0 100644 --- a/tests/unit/out/refcount/huffman.rs +++ b/tests/unit/out/refcount/huffman.rs @@ -200,7 +200,31 @@ impl MinHeap { } } } -impl ByteRepr for MinHeap {} +impl ByteRepr for MinHeap { + fn byte_size() -> usize { + 32 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.size.borrow()).to_bytes(&mut buf[0..4]); + (*self.capacity.borrow()).to_bytes(&mut buf[4..8]); + (*self.arr.borrow()).to_bytes(&mut buf[8..16]); + (*self.next.borrow()).to_bytes(&mut buf[16..20]); + (*self.alloc.borrow()).to_bytes(&mut buf[24..32]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + size: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + capacity: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + arr: Rc::new(RefCell::new( + ]>>>>::from_bytes(&buf[8..16]), + )), + next: Rc::new(RefCell::new(::from_bytes(&buf[16..20]))), + alloc: Rc::new(RefCell::new( + >>>::from_bytes(&buf[24..32]), + )), + } + } +} pub fn AllocMinHeap_1(capacity: i32) -> Option> { let capacity: Value = Rc::new(RefCell::new(capacity)); let minHeap: Value>> = diff --git a/tests/unit/out/refcount/immutable-deref-on-func-call.rs b/tests/unit/out/refcount/immutable-deref-on-func-call.rs index 416e1438..84ae55c9 100644 --- a/tests/unit/out/refcount/immutable-deref-on-func-call.rs +++ b/tests/unit/out/refcount/immutable-deref-on-func-call.rs @@ -25,6 +25,9 @@ impl Clone for Item { } } impl ByteRepr for Item { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.value.borrow()).to_bytes(&mut buf[0..4]); } diff --git a/tests/unit/out/refcount/implicit_autoref.rs b/tests/unit/out/refcount/implicit_autoref.rs index f9b022a4..bda4df7e 100644 --- a/tests/unit/out/refcount/implicit_autoref.rs +++ b/tests/unit/out/refcount/implicit_autoref.rs @@ -18,7 +18,19 @@ impl Clone for Holder { this } } -impl ByteRepr for Holder {} +impl ByteRepr for Holder { + fn byte_size() -> usize { + 24 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.v.borrow()).to_bytes(&mut buf[0..24]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + v: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), + } + } +} pub fn write_through_0(p: Ptr) { let p: Value> = Rc::new(RefCell::new(p)); (*p.borrow()).write(42); diff --git a/tests/unit/out/refcount/init.rs b/tests/unit/out/refcount/init.rs index f74601da..2fed9750 100644 --- a/tests/unit/out/refcount/init.rs +++ b/tests/unit/out/refcount/init.rs @@ -19,6 +19,9 @@ impl Clone for X { } } impl ByteRepr for X { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); } diff --git a/tests/unit/out/refcount/kruskal.rs b/tests/unit/out/refcount/kruskal.rs index e558cab3..e2e21b98 100644 --- a/tests/unit/out/refcount/kruskal.rs +++ b/tests/unit/out/refcount/kruskal.rs @@ -23,6 +23,9 @@ impl Clone for Edge { } } impl ByteRepr for Edge { + fn byte_size() -> usize { + 16 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.u.borrow()).to_bytes(&mut buf[0..4]); (*self.v.borrow()).to_bytes(&mut buf[4..8]); @@ -277,14 +280,52 @@ impl DisjointSet { } } } -impl ByteRepr for DisjointSet {} +impl ByteRepr for DisjointSet { + fn byte_size() -> usize { + 24 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.rank.borrow()).to_bytes(&mut buf[0..8]); + (*self.parent.borrow()).to_bytes(&mut buf[8..16]); + (*self.n.borrow()).to_bytes(&mut buf[16..20]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + rank: Rc::new(RefCell::new(>>>::from_bytes( + &buf[0..8], + ))), + parent: Rc::new(RefCell::new(>>>::from_bytes( + &buf[8..16], + ))), + n: Rc::new(RefCell::new(::from_bytes(&buf[16..20]))), + } + } +} #[derive(Default)] pub struct Graph { pub edges: Value>>>, pub V: Value, pub E: Value, } -impl ByteRepr for Graph {} +impl ByteRepr for Graph { + fn byte_size() -> usize { + 16 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.edges.borrow()).to_bytes(&mut buf[0..8]); + (*self.V.borrow()).to_bytes(&mut buf[8..12]); + (*self.E.borrow()).to_bytes(&mut buf[12..16]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + edges: Rc::new(RefCell::new(>>>::from_bytes( + &buf[0..8], + ))), + V: Rc::new(RefCell::new(::from_bytes(&buf[8..12]))), + E: Rc::new(RefCell::new(::from_bytes(&buf[12..16]))), + } + } +} pub fn MSTKruskal_2(graph: Ptr) -> f64 { ({ let _arr: Ptr>>> = (*graph.upgrade().deref()).edges.as_pointer(); diff --git a/tests/unit/out/refcount/local_anon_struct_collision.rs b/tests/unit/out/refcount/local_anon_struct_collision.rs index c4b23e73..d69250d0 100644 --- a/tests/unit/out/refcount/local_anon_struct_collision.rs +++ b/tests/unit/out/refcount/local_anon_struct_collision.rs @@ -13,6 +13,9 @@ pub fn first_0() -> i32 { pub y: Value, } impl ByteRepr for anon_1 { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); (*self.y.borrow()).to_bytes(&mut buf[4..8]); @@ -36,6 +39,9 @@ pub fn second_2() -> i32 { pub b: Value, } impl ByteRepr for anon_3 { + fn byte_size() -> usize { + 16 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.a.borrow()).to_bytes(&mut buf[0..8]); (*self.b.borrow()).to_bytes(&mut buf[8..16]); diff --git a/tests/unit/out/refcount/memcpy_struct_struct.rs b/tests/unit/out/refcount/memcpy_struct_struct.rs index 5ccc910e..158e7cff 100644 --- a/tests/unit/out/refcount/memcpy_struct_struct.rs +++ b/tests/unit/out/refcount/memcpy_struct_struct.rs @@ -21,6 +21,9 @@ impl Clone for Entry { } } impl ByteRepr for Entry { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.bits.borrow()).to_bytes(&mut buf[0..1]); (*self.value.borrow()).to_bytes(&mut buf[2..4]); @@ -77,9 +80,7 @@ fn main_0() -> i32 { .to_any() .memcpy( &(((table.as_pointer() as Ptr).offset(0 as isize)) as Ptr).to_any(), - (((*table_size.borrow()) as u64) - .wrapping_mul((::std::mem::size_of::() as u64)) - as usize) as usize, + (((*table_size.borrow()) as u64).wrapping_mul((4usize as u64)) as usize) as usize, ); (((table.as_pointer() as Ptr).offset((*table_size.borrow()) as isize)) as Ptr) .to_any() diff --git a/tests/unit/out/refcount/nested_structs.rs b/tests/unit/out/refcount/nested_structs.rs index 491cdf12..febf11a8 100644 --- a/tests/unit/out/refcount/nested_structs.rs +++ b/tests/unit/out/refcount/nested_structs.rs @@ -19,6 +19,9 @@ impl Clone for Level0_Level1_1_Level2_1_Level3_1 { } } impl ByteRepr for Level0_Level1_1_Level2_1_Level3_1 { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x1.borrow()).to_bytes(&mut buf[0..4]); } @@ -43,6 +46,9 @@ impl Clone for Level0_Level1_1_Level2_1_Level3_2 { } } impl ByteRepr for Level0_Level1_1_Level2_1_Level3_2 { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x1.borrow()).to_bytes(&mut buf[0..4]); (*self.x2.borrow()).to_bytes(&mut buf[4..8]); @@ -67,6 +73,9 @@ impl Clone for Level0_Level1_1_Level2_1 { } } impl ByteRepr for Level0_Level1_1_Level2_1 { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x1.borrow()).to_bytes(&mut buf[0..4]); } @@ -89,6 +98,9 @@ impl Clone for Level0_Level1_1 { } } impl ByteRepr for Level0_Level1_1 { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x1.borrow()).to_bytes(&mut buf[0..4]); } @@ -113,6 +125,9 @@ impl Clone for Level0_Level1_2 { } } impl ByteRepr for Level0_Level1_2 { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x1.borrow()).to_bytes(&mut buf[0..4]); (*self.x2.borrow()).to_bytes(&mut buf[4..8]); @@ -133,6 +148,9 @@ impl Clone for Level0 { } } impl ByteRepr for Level0 { + fn byte_size() -> usize { + 1 + } fn to_bytes(&self, buf: &mut [u8]) {} fn from_bytes(buf: &[u8]) -> Self { Self {} diff --git a/tests/unit/out/refcount/new_struct.rs b/tests/unit/out/refcount/new_struct.rs index 9885653c..05ba3965 100644 --- a/tests/unit/out/refcount/new_struct.rs +++ b/tests/unit/out/refcount/new_struct.rs @@ -21,6 +21,9 @@ impl Clone for Pair { } } impl ByteRepr for Pair { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); (*self.y.borrow()).to_bytes(&mut buf[4..8]); diff --git a/tests/unit/out/refcount/operator_less_than.rs b/tests/unit/out/refcount/operator_less_than.rs index cbf3d70b..94102602 100644 --- a/tests/unit/out/refcount/operator_less_than.rs +++ b/tests/unit/out/refcount/operator_less_than.rs @@ -62,6 +62,9 @@ impl Clone for Pair { } } impl ByteRepr for Pair { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); (*self.y.borrow()).to_bytes(&mut buf[4..8]); diff --git a/tests/unit/out/refcount/pod.rs b/tests/unit/out/refcount/pod.rs index 9e62ffde..5db49891 100644 --- a/tests/unit/out/refcount/pod.rs +++ b/tests/unit/out/refcount/pod.rs @@ -23,6 +23,9 @@ impl Clone for POD { } } impl ByteRepr for POD { + fn byte_size() -> usize { + 12 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x1.borrow()).to_bytes(&mut buf[0..4]); (*self.x2.borrow()).to_bytes(&mut buf[4..8]); diff --git a/tests/unit/out/refcount/pointers.rs b/tests/unit/out/refcount/pointers.rs index 065eb4bd..bbfc53c9 100644 --- a/tests/unit/out/refcount/pointers.rs +++ b/tests/unit/out/refcount/pointers.rs @@ -35,6 +35,9 @@ impl Clone for Test { } } impl ByteRepr for Test { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); } diff --git a/tests/unit/out/refcount/polymorphism.rs b/tests/unit/out/refcount/polymorphism.rs index b1f4297f..b50c4491 100644 --- a/tests/unit/out/refcount/polymorphism.rs +++ b/tests/unit/out/refcount/polymorphism.rs @@ -23,6 +23,9 @@ impl Clone for Dog { } } impl ByteRepr for Dog { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) {} fn from_bytes(buf: &[u8]) -> Self { Self {} @@ -47,6 +50,9 @@ impl Clone for Cat { } } impl ByteRepr for Cat { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) {} fn from_bytes(buf: &[u8]) -> Self { Self {} diff --git a/tests/unit/out/refcount/push_emplace_back.rs b/tests/unit/out/refcount/push_emplace_back.rs index 0ee8c04b..c6683ebb 100644 --- a/tests/unit/out/refcount/push_emplace_back.rs +++ b/tests/unit/out/refcount/push_emplace_back.rs @@ -19,6 +19,9 @@ impl Clone for Chunk { } } impl ByteRepr for Chunk { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.data.borrow()).to_bytes(&mut buf[0..4]); } @@ -67,7 +70,23 @@ impl Clone for JPEGData { this } } -impl ByteRepr for JPEGData {} +impl ByteRepr for JPEGData { + fn byte_size() -> usize { + 48 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.com_data.borrow()).to_bytes(&mut buf[0..24]); + (*self.app_data.borrow()).to_bytes(&mut buf[24..48]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + com_data: Rc::new(RefCell::new(>>>::from_bytes(&buf[0..24]))), + app_data: Rc::new(RefCell::new(>>>::from_bytes( + &buf[24..48], + ))), + } + } +} pub fn push_param_0(dest: Ptr>>>) { let dest: Value>>>> = Rc::new(RefCell::new(dest)); ((*dest.borrow()).to_strong().as_pointer() as Ptr>>>).with_mut( diff --git a/tests/unit/out/refcount/random.rs b/tests/unit/out/refcount/random.rs index 3b1057f8..aa0e5a31 100644 --- a/tests/unit/out/refcount/random.rs +++ b/tests/unit/out/refcount/random.rs @@ -82,6 +82,9 @@ impl Clone for X1 { } } impl ByteRepr for X1 { + fn byte_size() -> usize { + 1 + } fn to_bytes(&self, buf: &mut [u8]) {} fn from_bytes(buf: &[u8]) -> Self { Self {} diff --git a/tests/unit/out/refcount/reinterpret_cast_struct.rs b/tests/unit/out/refcount/reinterpret_cast_struct.rs index 9e2370a1..1c9e14b5 100644 --- a/tests/unit/out/refcount/reinterpret_cast_struct.rs +++ b/tests/unit/out/refcount/reinterpret_cast_struct.rs @@ -21,6 +21,9 @@ impl Clone for Point { } } impl ByteRepr for Point { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); (*self.y.borrow()).to_bytes(&mut buf[4..8]); diff --git a/tests/unit/out/refcount/reinterpret_cast_struct_to_struct.rs b/tests/unit/out/refcount/reinterpret_cast_struct_to_struct.rs index 0f065102..5b5d82c9 100644 --- a/tests/unit/out/refcount/reinterpret_cast_struct_to_struct.rs +++ b/tests/unit/out/refcount/reinterpret_cast_struct_to_struct.rs @@ -21,6 +21,9 @@ impl Clone for Point { } } impl ByteRepr for Point { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); (*self.y.borrow()).to_bytes(&mut buf[4..8]); @@ -47,6 +50,9 @@ impl Clone for Pair { } } impl ByteRepr for Pair { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.first.borrow()).to_bytes(&mut buf[0..4]); (*self.second.borrow()).to_bytes(&mut buf[4..8]); diff --git a/tests/unit/out/refcount/reserved_keywords.rs b/tests/unit/out/refcount/reserved_keywords.rs index b670988f..5258cfab 100644 --- a/tests/unit/out/refcount/reserved_keywords.rs +++ b/tests/unit/out/refcount/reserved_keywords.rs @@ -93,6 +93,9 @@ impl Clone for S { } } impl ByteRepr for S { + fn byte_size() -> usize { + 152 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.as_.borrow()).to_bytes(&mut buf[0..4]); (*self.async_.borrow()).to_bytes(&mut buf[4..8]); diff --git a/tests/unit/out/refcount/static_var_in_class.rs b/tests/unit/out/refcount/static_var_in_class.rs index 35e012e7..d08a4f63 100644 --- a/tests/unit/out/refcount/static_var_in_class.rs +++ b/tests/unit/out/refcount/static_var_in_class.rs @@ -23,6 +23,9 @@ impl Clone for C { } } impl ByteRepr for C { + fn byte_size() -> usize { + 1 + } fn to_bytes(&self, buf: &mut [u8]) {} fn from_bytes(buf: &[u8]) -> Self { Self {} @@ -40,6 +43,9 @@ impl Clone for S { } } impl ByteRepr for S { + fn byte_size() -> usize { + 1 + } fn to_bytes(&self, buf: &mut [u8]) {} fn from_bytes(buf: &[u8]) -> Self { Self {} diff --git a/tests/unit/out/refcount/struct_ctor.rs b/tests/unit/out/refcount/struct_ctor.rs index d5a4c660..430fd275 100644 --- a/tests/unit/out/refcount/struct_ctor.rs +++ b/tests/unit/out/refcount/struct_ctor.rs @@ -40,6 +40,9 @@ impl Clone for StructWithCtor { } } impl ByteRepr for StructWithCtor { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x1_.borrow()).to_bytes(&mut buf[0..4]); (*self.x2_.borrow()).to_bytes(&mut buf[4..8]); diff --git a/tests/unit/out/refcount/struct_ptr.rs b/tests/unit/out/refcount/struct_ptr.rs index 4defc67a..beb54800 100644 --- a/tests/unit/out/refcount/struct_ptr.rs +++ b/tests/unit/out/refcount/struct_ptr.rs @@ -19,6 +19,9 @@ impl Clone for XX { } } impl ByteRepr for XX { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); } diff --git a/tests/unit/out/refcount/typedef-anon-struct.rs b/tests/unit/out/refcount/typedef-anon-struct.rs index 251d05d8..80e81458 100644 --- a/tests/unit/out/refcount/typedef-anon-struct.rs +++ b/tests/unit/out/refcount/typedef-anon-struct.rs @@ -21,6 +21,9 @@ impl Clone for Outer_RunInfo { } } impl ByteRepr for Outer_RunInfo { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.block_idx.borrow()).to_bytes(&mut buf[0..4]); (*self.num_extra_zero_runs.borrow()).to_bytes(&mut buf[4..8]); @@ -44,7 +47,19 @@ impl Clone for Outer { this } } -impl ByteRepr for Outer {} +impl ByteRepr for Outer { + fn byte_size() -> usize { + 24 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.runs.borrow()).to_bytes(&mut buf[0..24]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + runs: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), + } + } +} pub fn main() { std::process::exit(main_0()); } diff --git a/tests/unit/out/refcount/unique_ptr.rs b/tests/unit/out/refcount/unique_ptr.rs index 9221a605..9d4eb0eb 100644 --- a/tests/unit/out/refcount/unique_ptr.rs +++ b/tests/unit/out/refcount/unique_ptr.rs @@ -15,7 +15,19 @@ impl SafePointer { (*(*self.ptr.borrow_mut()).as_ref().unwrap().borrow_mut()).prefix_inc(); } } -impl ByteRepr for SafePointer {} +impl ByteRepr for SafePointer { + fn byte_size() -> usize { + 8 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.ptr.borrow()).to_bytes(&mut buf[0..8]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + ptr: Rc::new(RefCell::new(>>::from_bytes(&buf[0..8]))), + } + } +} #[derive(Default)] pub struct Pair { pub x: Value, @@ -31,6 +43,9 @@ impl Clone for Pair { } } impl ByteRepr for Pair { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); (*self.y.borrow()).to_bytes(&mut buf[4..8]); diff --git a/tests/unit/out/refcount/unique_ptr_const_deref.rs b/tests/unit/out/refcount/unique_ptr_const_deref.rs index ee468020..8763aa17 100644 --- a/tests/unit/out/refcount/unique_ptr_const_deref.rs +++ b/tests/unit/out/refcount/unique_ptr_const_deref.rs @@ -10,7 +10,19 @@ use std::rc::{Rc, Weak}; pub struct Holder { pub val: Value>>, } -impl ByteRepr for Holder {} +impl ByteRepr for Holder { + fn byte_size() -> usize { + 8 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.val.borrow()).to_bytes(&mut buf[0..8]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + val: Rc::new(RefCell::new(>>::from_bytes(&buf[0..8]))), + } + } +} pub fn read_val_0(h: Ptr) -> i32 { let h: Value> = Rc::new(RefCell::new(h)); return (*(*(*(*h.borrow()).upgrade().deref()).val.borrow()) diff --git a/tests/unit/out/refcount/unique_ptr_nested.rs b/tests/unit/out/refcount/unique_ptr_nested.rs index 94cfb1d5..73a07682 100644 --- a/tests/unit/out/refcount/unique_ptr_nested.rs +++ b/tests/unit/out/refcount/unique_ptr_nested.rs @@ -21,6 +21,9 @@ impl Clone for Inner { } } impl ByteRepr for Inner { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); (*self.y.borrow()).to_bytes(&mut buf[4..8]); @@ -36,7 +39,19 @@ impl ByteRepr for Inner { pub struct Outer { pub inner: Value>>, } -impl ByteRepr for Outer {} +impl ByteRepr for Outer { + fn byte_size() -> usize { + 8 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.inner.borrow()).to_bytes(&mut buf[0..8]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + inner: Rc::new(RefCell::new(>>::from_bytes(&buf[0..8]))), + } + } +} pub fn main() { std::process::exit(main_0()); } diff --git a/tests/unit/out/refcount/unique_ptr_struct.rs b/tests/unit/out/refcount/unique_ptr_struct.rs index ec65ca5b..bc8381b7 100644 --- a/tests/unit/out/refcount/unique_ptr_struct.rs +++ b/tests/unit/out/refcount/unique_ptr_struct.rs @@ -21,6 +21,9 @@ impl Clone for Point { } } impl ByteRepr for Point { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); (*self.y.borrow()).to_bytes(&mut buf[4..8]); diff --git a/tests/unit/out/refcount/va_arg_struct_ctx.rs b/tests/unit/out/refcount/va_arg_struct_ctx.rs index 37effcea..b6b031f5 100644 --- a/tests/unit/out/refcount/va_arg_struct_ctx.rs +++ b/tests/unit/out/refcount/va_arg_struct_ctx.rs @@ -12,6 +12,9 @@ pub struct context { pub last_error: Value, } impl ByteRepr for context { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.verbose.borrow()).to_bytes(&mut buf[0..4]); (*self.last_error.borrow()).to_bytes(&mut buf[4..8]); diff --git a/tests/unit/out/refcount/void_cast.rs b/tests/unit/out/refcount/void_cast.rs index aa18bf00..f8b0af11 100644 --- a/tests/unit/out/refcount/void_cast.rs +++ b/tests/unit/out/refcount/void_cast.rs @@ -22,7 +22,19 @@ impl Clone for NonTrivial { this } } -impl ByteRepr for NonTrivial {} +impl ByteRepr for NonTrivial { + fn byte_size() -> usize { + 24 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.data.borrow()).to_bytes(&mut buf[0..24]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + data: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), + } + } +} pub fn unused_ref_param_1(x: Ptr) { (*x.upgrade().deref()).clone(); } @@ -50,6 +62,9 @@ impl Clone for Holder { } } impl ByteRepr for Holder { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.field.borrow()).to_bytes(&mut buf[0..4]); } From 5af65da6bde510f669d8abf74019e3f04b843ed0 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 25 Jun 2026 15:13:34 +0100 Subject: [PATCH 06/15] Add panic default implementations --- libcc2rs/src/reinterpret.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/libcc2rs/src/reinterpret.rs b/libcc2rs/src/reinterpret.rs index c554814f..1d428a28 100644 --- a/libcc2rs/src/reinterpret.rs +++ b/libcc2rs/src/reinterpret.rs @@ -8,16 +8,25 @@ pub trait ByteRepr: 'static { where Self: Sized, { - std::mem::size_of::() + panic!( + "byte_size is not implemented for {}", + std::any::type_name::() + ) } fn to_bytes(&self, _buf: &mut [u8]) { - panic!("ByteRepr not supported for this type"); + panic!( + "to_bytes is not implemented for {}", + std::any::type_name::() + ) } fn from_bytes(_buf: &[u8]) -> Self where Self: Sized, { - panic!("ByteRepr not supported for this type"); + panic!( + "from_bytes is not implemented for {}", + std::any::type_name::() + ) } } From 8084fc99591c0205151e9b995babbc96384523cc Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 25 Jun 2026 15:13:50 +0100 Subject: [PATCH 07/15] Implement byte_size for primitives --- libcc2rs/src/reinterpret.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libcc2rs/src/reinterpret.rs b/libcc2rs/src/reinterpret.rs index 1d428a28..b496f8b2 100644 --- a/libcc2rs/src/reinterpret.rs +++ b/libcc2rs/src/reinterpret.rs @@ -33,6 +33,10 @@ pub trait ByteRepr: 'static { macro_rules! impl_byte_repr { ($ty:ty) => { impl ByteRepr for $ty { + #[inline] + fn byte_size() -> usize { + std::mem::size_of::<$ty>() + } #[inline] fn to_bytes(&self, buf: &mut [u8]) { buf.copy_from_slice(&self.to_ne_bytes()); @@ -61,6 +65,10 @@ impl_byte_repr!(f32); impl_byte_repr!(f64); impl ByteRepr for bool { + #[inline] + fn byte_size() -> usize { + 1 + } #[inline] fn to_bytes(&self, buf: &mut [u8]) { buf[0] = *self as u8; From 532c0b58e1261b6306fd6d2076e2cc1df8740c3a Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 25 Jun 2026 16:00:54 +0100 Subject: [PATCH 08/15] Allow enums to have byterepr --- cpp2rust/converter/converter_lib.cpp | 5 +- libcc2rs/src/rc.rs | 44 +++++++-------- tests/unit/out/refcount/anonymous_enum.rs | 56 ++++++++++++++++++- tests/unit/out/refcount/anonymous_enum_c.rs | 56 ++++++++++++++++++- tests/unit/out/refcount/c_struct.rs | 26 ++++++++- .../out/refcount/enum_default_in_static.rs | 3 + 6 files changed, 161 insertions(+), 29 deletions(-) diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 4c4901a4..3b4a795c 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -201,10 +201,7 @@ bool IsMut(clang::QualType qual_type) { } bool TypeImplementsByteRepr(clang::QualType qt) { - if (qt->isEnumeralType()) { - return false; - } - if (qt->isIntegerType() || qt->isFloatingType()) { + if (qt->isIntegerType() || qt->isFloatingType() || qt->isEnumeralType()) { return true; } if (const auto *arr = qt->getAsArrayTypeUnsafe()) { diff --git a/libcc2rs/src/rc.rs b/libcc2rs/src/rc.rs index 6a643d6f..ac09c80c 100644 --- a/libcc2rs/src/rc.rs +++ b/libcc2rs/src/rc.rs @@ -84,8 +84,8 @@ impl fmt::Debug for PtrKind { PtrKind::HeapSingle(w) => write!(f, "HeapSingle({:?})", w.as_ptr()), PtrKind::StackArray(w) => write!(f, "StackArray({:?})", w.as_ptr()), PtrKind::HeapArray(w) => write!(f, "HeapArray({:?})", w.as_ptr()), - PtrKind::Reinterpreted(view) => { - write!(f, "Reinterpreted(0x{:x})", view.alloc.address()) + PtrKind::Reinterpreted(data) => { + write!(f, "Reinterpreted(0x{:x})", data.alloc.address()) } } } @@ -100,7 +100,7 @@ impl Clone for PtrKind { PtrKind::HeapSingle(weak) => PtrKind::HeapSingle(weak.clone()), PtrKind::StackArray(weak) => PtrKind::StackArray(weak.clone()), PtrKind::HeapArray(weak) => PtrKind::HeapArray(weak.clone()), - PtrKind::Reinterpreted(view) => PtrKind::Reinterpreted(Rc::clone(view)), + PtrKind::Reinterpreted(data) => PtrKind::Reinterpreted(Rc::clone(data)), } } } @@ -112,7 +112,7 @@ impl PtrKind { PtrKind::StackSingle(w) | PtrKind::HeapSingle(w) => w.as_ptr() as usize, PtrKind::Vec(w) => w.as_ptr() as usize, PtrKind::StackArray(w) | PtrKind::HeapArray(w) => w.as_ptr() as usize, - PtrKind::Reinterpreted(view) => view.alloc.address(), + PtrKind::Reinterpreted(data) => data.alloc.address(), } } } @@ -258,7 +258,7 @@ impl Ptr { #[inline] fn elem_step(&self) -> usize { match &self.kind { - PtrKind::Reinterpreted(view) => view.elem_byte_size, + PtrKind::Reinterpreted(data) => data.elem_byte_size, _ => 1, } } @@ -272,7 +272,7 @@ impl Ptr { PtrKind::StackArray(weak) | PtrKind::HeapArray(weak) => { weak.upgrade().expect("ub: dangling pointer").borrow().len() } - PtrKind::Reinterpreted(view) => view.alloc.total_byte_len() / view.elem_byte_size, + PtrKind::Reinterpreted(data) => data.alloc.total_byte_len() / data.elem_byte_size, } } @@ -291,7 +291,7 @@ impl Ptr { .expect("ub: dangling pointer") .borrow() .is_empty(), - PtrKind::Reinterpreted(view) => self.offset >= view.alloc.total_byte_len(), + PtrKind::Reinterpreted(data) => self.offset >= data.alloc.total_byte_len(), } } @@ -346,8 +346,8 @@ impl Ptr { rc: weak.upgrade().expect("ub: dangling pointer"), offset: self.offset, }, - PtrKind::Reinterpreted(view) => StrongPtr::Reinterpreted { - alloc: Rc::clone(&view.alloc), + PtrKind::Reinterpreted(data) => StrongPtr::Reinterpreted { + alloc: Rc::clone(&data.alloc), byte_offset: self.offset, cell: RefCell::new(None), }, @@ -372,10 +372,10 @@ impl Ptr { let rc = weak.upgrade().expect("ub: dangling pointer"); rc.borrow_mut()[self.offset] = value; } - PtrKind::Reinterpreted(view) => { + PtrKind::Reinterpreted(data) => { let mut buf = vec![0u8; T::byte_size()]; value.to_bytes(&mut buf); - view.alloc.write_bytes(self.offset, &buf); + data.alloc.write_bytes(self.offset, &buf); } } } @@ -417,7 +417,7 @@ impl Ptr { Rc::new(SliceOriginalAlloc { weak: weak.clone() }), src_byte_off, ), - PtrKind::Reinterpreted(view) => (Rc::clone(&view.alloc), self.offset), + PtrKind::Reinterpreted(data) => (Rc::clone(&data.alloc), self.offset), }; Ptr { @@ -452,13 +452,13 @@ impl Ptr { let mut borrow = rc.borrow_mut(); f(&mut borrow[self.offset]) } - PtrKind::Reinterpreted(view) => { + PtrKind::Reinterpreted(data) => { let mut buf = vec![0u8; T::byte_size()]; - view.alloc.read_bytes(self.offset, &mut buf); + data.alloc.read_bytes(self.offset, &mut buf); let mut val = T::from_bytes(&buf); let ret = f(&mut val); val.to_bytes(&mut buf); - view.alloc.write_bytes(self.offset, &buf); + data.alloc.write_bytes(self.offset, &buf); ret } } @@ -485,9 +485,9 @@ impl Ptr { let borrow = rc.borrow(); f(&borrow[self.offset]) } - PtrKind::Reinterpreted(view) => { + PtrKind::Reinterpreted(data) => { let mut buf = vec![0u8; T::byte_size()]; - view.alloc.read_bytes(self.offset, &mut buf); + data.alloc.read_bytes(self.offset, &mut buf); let val = T::from_bytes(&buf); f(&val) } @@ -512,9 +512,9 @@ impl Ptr { PtrKind::StackArray(ref weak) | PtrKind::HeapArray(ref weak) => { weak.upgrade().expect("ub: dangling pointer").borrow()[self.offset].clone() } - PtrKind::Reinterpreted(ref view) => { + PtrKind::Reinterpreted(ref data) => { let mut buf = vec![0u8; T::byte_size()]; - view.alloc.read_bytes(self.offset, &mut buf); + data.alloc.read_bytes(self.offset, &mut buf); T::from_bytes(&buf) } } @@ -909,7 +909,7 @@ impl fmt::Debug for Ptr { (Weak::as_ptr(w) as usize).wrapping_add(self.byte_offset()) } PtrKind::Vec(w) => (Weak::as_ptr(w) as usize).wrapping_add(self.byte_offset()), - PtrKind::Reinterpreted(view) => view.alloc.address().wrapping_add(self.byte_offset()), + PtrKind::Reinterpreted(data) => data.alloc.address().wrapping_add(self.byte_offset()), }; write!(f, "0x{:x}", addr) } @@ -1005,9 +1005,9 @@ impl Ptr { let raw = strong.borrow(); raw[start..end].to_vec() } - PtrKind::Reinterpreted(ref view) => { + PtrKind::Reinterpreted(ref data) => { let mut buf = vec![0u8; end.wrapping_sub(start)]; - view.alloc.read_bytes(start, &mut buf); + data.alloc.read_bytes(start, &mut buf); buf } } diff --git a/tests/unit/out/refcount/anonymous_enum.rs b/tests/unit/out/refcount/anonymous_enum.rs index f63deffd..47298b56 100644 --- a/tests/unit/out/refcount/anonymous_enum.rs +++ b/tests/unit/out/refcount/anonymous_enum.rs @@ -22,6 +22,14 @@ impl From for anon_0 { } } libcc2rs::impl_enum_inc_dec!(anon_0); +impl ByteRepr for anon_0 { + fn to_bytes(&self, buf: &mut [u8]) { + (*self as i32).to_bytes(buf); + } + fn from_bytes(buf: &[u8]) -> Self { + ::from(i32::from_bytes(buf)) + } +} #[derive(Clone, Copy, PartialEq, Debug, Default)] enum anon_1 { #[default] @@ -38,6 +46,14 @@ impl From for anon_1 { } } libcc2rs::impl_enum_inc_dec!(anon_1); +impl ByteRepr for anon_1 { + fn to_bytes(&self, buf: &mut [u8]) { + (*self as i32).to_bytes(buf); + } + fn from_bytes(buf: &[u8]) -> Self { + ::from(i32::from_bytes(buf)) + } +} #[derive(Default)] pub struct S { pub a: Value, @@ -79,6 +95,14 @@ impl From for TdEnum { } } libcc2rs::impl_enum_inc_dec!(TdEnum); +impl ByteRepr for TdEnum { + fn to_bytes(&self, buf: &mut [u8]) { + (*self as i32).to_bytes(buf); + } + fn from_bytes(buf: &[u8]) -> Self { + ::from(i32::from_bytes(buf)) + } +} #[derive(Clone, Copy, PartialEq, Debug, Default)] enum anon_2 { #[default] @@ -95,6 +119,14 @@ impl From for anon_2 { } } libcc2rs::impl_enum_inc_dec!(anon_2); +impl ByteRepr for anon_2 { + fn to_bytes(&self, buf: &mut [u8]) { + (*self as i32).to_bytes(buf); + } + fn from_bytes(buf: &[u8]) -> Self { + ::from(i32::from_bytes(buf)) + } +} #[derive(Default)] pub struct WithAnonField { pub a: Value, @@ -109,7 +141,21 @@ impl Clone for WithAnonField { this } } -impl ByteRepr for WithAnonField {} +impl ByteRepr for WithAnonField { + fn byte_size() -> usize { + 8 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.a.borrow()).to_bytes(&mut buf[0..4]); + (*self.field.borrow()).to_bytes(&mut buf[4..8]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + a: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + field: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + } + } +} pub fn main() { std::process::exit(main_0()); } @@ -130,6 +176,14 @@ fn main_0() -> i32 { } } libcc2rs::impl_enum_inc_dec!(anon_3); + impl ByteRepr for anon_3 { + fn to_bytes(&self, buf: &mut [u8]) { + (*self as i32).to_bytes(buf); + } + fn from_bytes(buf: &[u8]) -> Self { + ::from(i32::from_bytes(buf)) + } + }; assert!(((anon_0::FIRST_A as i32) != (anon_0::FIRST_B as i32))); assert!(((anon_1::SECOND_A as i32) != (anon_1::SECOND_B as i32))); assert!(((anon_3::THIRD_A as i32) != (anon_3::THIRD_B as i32))); diff --git a/tests/unit/out/refcount/anonymous_enum_c.rs b/tests/unit/out/refcount/anonymous_enum_c.rs index 43dc943b..a851a2b5 100644 --- a/tests/unit/out/refcount/anonymous_enum_c.rs +++ b/tests/unit/out/refcount/anonymous_enum_c.rs @@ -22,6 +22,14 @@ impl From for anon_0 { } } libcc2rs::impl_enum_inc_dec!(anon_0); +impl ByteRepr for anon_0 { + fn to_bytes(&self, buf: &mut [u8]) { + (*self as i32).to_bytes(buf); + } + fn from_bytes(buf: &[u8]) -> Self { + ::from(i32::from_bytes(buf)) + } +} #[derive(Clone, Copy, PartialEq, Debug, Default)] enum anon_1 { #[default] @@ -38,6 +46,14 @@ impl From for anon_1 { } } libcc2rs::impl_enum_inc_dec!(anon_1); +impl ByteRepr for anon_1 { + fn to_bytes(&self, buf: &mut [u8]) { + (*self as i32).to_bytes(buf); + } + fn from_bytes(buf: &[u8]) -> Self { + ::from(i32::from_bytes(buf)) + } +} #[derive(Default)] pub struct S { pub a: Value, @@ -71,6 +87,14 @@ impl From for TdEnum_enum { } } libcc2rs::impl_enum_inc_dec!(TdEnum_enum); +impl ByteRepr for TdEnum_enum { + fn to_bytes(&self, buf: &mut [u8]) { + (*self as i32).to_bytes(buf); + } + fn from_bytes(buf: &[u8]) -> Self { + ::from(i32::from_bytes(buf)) + } +} #[derive(Clone, Copy, PartialEq, Debug, Default)] enum anon_2 { #[default] @@ -87,12 +111,34 @@ impl From for anon_2 { } } libcc2rs::impl_enum_inc_dec!(anon_2); +impl ByteRepr for anon_2 { + fn to_bytes(&self, buf: &mut [u8]) { + (*self as i32).to_bytes(buf); + } + fn from_bytes(buf: &[u8]) -> Self { + ::from(i32::from_bytes(buf)) + } +} #[derive(Default)] pub struct WithAnonField { pub a: Value, pub field: Value, } -impl ByteRepr for WithAnonField {} +impl ByteRepr for WithAnonField { + fn byte_size() -> usize { + 8 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.a.borrow()).to_bytes(&mut buf[0..4]); + (*self.field.borrow()).to_bytes(&mut buf[4..8]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + a: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + field: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + } + } +} pub fn main() { std::process::exit(main_0()); } @@ -113,6 +159,14 @@ fn main_0() -> i32 { } } libcc2rs::impl_enum_inc_dec!(anon_3); + impl ByteRepr for anon_3 { + fn to_bytes(&self, buf: &mut [u8]) { + (*self as i32).to_bytes(buf); + } + fn from_bytes(buf: &[u8]) -> Self { + ::from(i32::from_bytes(buf)) + } + }; assert!(((((anon_0::FIRST_A as i32) != (anon_0::FIRST_B as i32)) as i32) != 0)); assert!(((((anon_1::SECOND_A as i32) != (anon_1::SECOND_B as i32)) as i32) != 0)); assert!(((((anon_3::THIRD_A as i32) != (anon_3::THIRD_B as i32)) as i32) != 0)); diff --git a/tests/unit/out/refcount/c_struct.rs b/tests/unit/out/refcount/c_struct.rs index a0985ec8..1214d4a9 100644 --- a/tests/unit/out/refcount/c_struct.rs +++ b/tests/unit/out/refcount/c_struct.rs @@ -70,6 +70,14 @@ impl From for Color { } } libcc2rs::impl_enum_inc_dec!(Color); +impl ByteRepr for Color { + fn to_bytes(&self, buf: &mut [u8]) { + (*self as i32).to_bytes(buf); + } + fn from_bytes(buf: &[u8]) -> Self { + ::from(i32::from_bytes(buf)) + } +} #[derive(Default)] pub struct Inner { pub a: Value, @@ -96,7 +104,23 @@ pub struct Container { pub color: Value, pub count: Value, } -impl ByteRepr for Container {} +impl ByteRepr for Container { + fn byte_size() -> usize { + 16 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.inner.borrow()).to_bytes(&mut buf[0..8]); + (*self.color.borrow()).to_bytes(&mut buf[8..12]); + (*self.count.borrow()).to_bytes(&mut buf[12..16]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + inner: Rc::new(RefCell::new(::from_bytes(&buf[0..8]))), + color: Rc::new(RefCell::new(::from_bytes(&buf[8..12]))), + count: Rc::new(RefCell::new(::from_bytes(&buf[12..16]))), + } + } +} pub fn main() { std::process::exit(main_0()); } diff --git a/tests/unit/out/refcount/enum_default_in_static.rs b/tests/unit/out/refcount/enum_default_in_static.rs index 0e6f4c29..866240a2 100644 --- a/tests/unit/out/refcount/enum_default_in_static.rs +++ b/tests/unit/out/refcount/enum_default_in_static.rs @@ -38,6 +38,9 @@ pub struct Config { pub mode: Value, } impl ByteRepr for Config { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.count.borrow()).to_bytes(&mut buf[0..4]); (*self.mode.borrow()).to_bytes(&mut buf[4..8]); From 0573f9cc7965a508fa7aa25b62ccf82e4ba8ecd3 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 25 Jun 2026 17:07:45 +0100 Subject: [PATCH 09/15] Don't add ByteRepr for system header types --- cpp2rust/converter/converter_lib.cpp | 4 ++ .../out/refcount/array_of_noncopy_struct.rs | 16 +------ tests/unit/out/refcount/class_templates.rs | 42 ++----------------- .../refcount/foreach_disjoint_field_borrow.rs | 16 +------ tests/unit/out/refcount/huffman.rs | 26 +----------- tests/unit/out/refcount/implicit_autoref.rs | 14 +------ tests/unit/out/refcount/kruskal.rs | 42 +------------------ tests/unit/out/refcount/push_emplace_back.rs | 18 +------- .../unit/out/refcount/typedef-anon-struct.rs | 14 +------ tests/unit/out/refcount/unique_ptr.rs | 14 +------ .../out/refcount/unique_ptr_const_deref.rs | 14 +------ tests/unit/out/refcount/unique_ptr_nested.rs | 14 +------ tests/unit/out/refcount/void_cast.rs | 14 +------ 13 files changed, 19 insertions(+), 229 deletions(-) diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 3b4a795c..2eafb1c1 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -208,6 +208,10 @@ bool TypeImplementsByteRepr(clang::QualType qt) { return TypeImplementsByteRepr(arr->getElementType()); } if (const auto *rd = qt->getAsRecordDecl()) { + if (rd->getASTContext().getSourceManager().isInSystemHeader( + rd->getLocation())) { + return false; + } if (rd->isUnion()) { return true; } diff --git a/tests/unit/out/refcount/array_of_noncopy_struct.rs b/tests/unit/out/refcount/array_of_noncopy_struct.rs index 0c91af6d..4af56349 100644 --- a/tests/unit/out/refcount/array_of_noncopy_struct.rs +++ b/tests/unit/out/refcount/array_of_noncopy_struct.rs @@ -20,21 +20,7 @@ impl Clone for NonCopy { this } } -impl ByteRepr for NonCopy { - fn byte_size() -> usize { - 32 - } - fn to_bytes(&self, buf: &mut [u8]) { - (*self.data.borrow()).to_bytes(&mut buf[0..24]); - (*self.tag.borrow()).to_bytes(&mut buf[24..28]); - } - fn from_bytes(buf: &[u8]) -> Self { - Self { - data: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), - tag: Rc::new(RefCell::new(::from_bytes(&buf[24..28]))), - } - } -} +impl ByteRepr for NonCopy {} pub fn main() { std::process::exit(main_0()); } diff --git a/tests/unit/out/refcount/class_templates.rs b/tests/unit/out/refcount/class_templates.rs index 183fbd41..3cbce86e 100644 --- a/tests/unit/out/refcount/class_templates.rs +++ b/tests/unit/out/refcount/class_templates.rs @@ -42,19 +42,7 @@ impl Clone for MyContainer_int_ { this } } -impl ByteRepr for MyContainer_int_ { - fn byte_size() -> usize { - 24 - } - fn to_bytes(&self, buf: &mut [u8]) { - (*self.vec_.borrow()).to_bytes(&mut buf[0..24]); - } - fn from_bytes(buf: &[u8]) -> Self { - Self { - vec_: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), - } - } -} +impl ByteRepr for MyContainer_int_ {} #[derive(Default)] pub struct MyContainer_char_ { vec_: Value>, @@ -91,19 +79,7 @@ impl Clone for MyContainer_char_ { this } } -impl ByteRepr for MyContainer_char_ { - fn byte_size() -> usize { - 24 - } - fn to_bytes(&self, buf: &mut [u8]) { - (*self.vec_.borrow()).to_bytes(&mut buf[0..24]); - } - fn from_bytes(buf: &[u8]) -> Self { - Self { - vec_: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), - } - } -} +impl ByteRepr for MyContainer_char_ {} #[derive(Default)] pub struct MyContainer_float_ { vec_: Value>, @@ -140,19 +116,7 @@ impl Clone for MyContainer_float_ { this } } -impl ByteRepr for MyContainer_float_ { - fn byte_size() -> usize { - 24 - } - fn to_bytes(&self, buf: &mut [u8]) { - (*self.vec_.borrow()).to_bytes(&mut buf[0..24]); - } - fn from_bytes(buf: &[u8]) -> Self { - Self { - vec_: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), - } - } -} +impl ByteRepr for MyContainer_float_ {} pub fn main() { std::process::exit(main_0()); } diff --git a/tests/unit/out/refcount/foreach_disjoint_field_borrow.rs b/tests/unit/out/refcount/foreach_disjoint_field_borrow.rs index 57c56051..66c9e892 100644 --- a/tests/unit/out/refcount/foreach_disjoint_field_borrow.rs +++ b/tests/unit/out/refcount/foreach_disjoint_field_borrow.rs @@ -20,21 +20,7 @@ impl Clone for S { this } } -impl ByteRepr for S { - fn byte_size() -> usize { - 32 - } - fn to_bytes(&self, buf: &mut [u8]) { - (*self.v.borrow()).to_bytes(&mut buf[0..24]); - (*self.a.borrow()).to_bytes(&mut buf[24..28]); - } - fn from_bytes(buf: &[u8]) -> Self { - Self { - v: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), - a: Rc::new(RefCell::new(::from_bytes(&buf[24..28]))), - } - } -} +impl ByteRepr for S {} pub fn main() { std::process::exit(main_0()); } diff --git a/tests/unit/out/refcount/huffman.rs b/tests/unit/out/refcount/huffman.rs index c36e85e0..f320d46a 100644 --- a/tests/unit/out/refcount/huffman.rs +++ b/tests/unit/out/refcount/huffman.rs @@ -200,31 +200,7 @@ impl MinHeap { } } } -impl ByteRepr for MinHeap { - fn byte_size() -> usize { - 32 - } - fn to_bytes(&self, buf: &mut [u8]) { - (*self.size.borrow()).to_bytes(&mut buf[0..4]); - (*self.capacity.borrow()).to_bytes(&mut buf[4..8]); - (*self.arr.borrow()).to_bytes(&mut buf[8..16]); - (*self.next.borrow()).to_bytes(&mut buf[16..20]); - (*self.alloc.borrow()).to_bytes(&mut buf[24..32]); - } - fn from_bytes(buf: &[u8]) -> Self { - Self { - size: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), - capacity: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), - arr: Rc::new(RefCell::new( - ]>>>>::from_bytes(&buf[8..16]), - )), - next: Rc::new(RefCell::new(::from_bytes(&buf[16..20]))), - alloc: Rc::new(RefCell::new( - >>>::from_bytes(&buf[24..32]), - )), - } - } -} +impl ByteRepr for MinHeap {} pub fn AllocMinHeap_1(capacity: i32) -> Option> { let capacity: Value = Rc::new(RefCell::new(capacity)); let minHeap: Value>> = diff --git a/tests/unit/out/refcount/implicit_autoref.rs b/tests/unit/out/refcount/implicit_autoref.rs index bda4df7e..f9b022a4 100644 --- a/tests/unit/out/refcount/implicit_autoref.rs +++ b/tests/unit/out/refcount/implicit_autoref.rs @@ -18,19 +18,7 @@ impl Clone for Holder { this } } -impl ByteRepr for Holder { - fn byte_size() -> usize { - 24 - } - fn to_bytes(&self, buf: &mut [u8]) { - (*self.v.borrow()).to_bytes(&mut buf[0..24]); - } - fn from_bytes(buf: &[u8]) -> Self { - Self { - v: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), - } - } -} +impl ByteRepr for Holder {} pub fn write_through_0(p: Ptr) { let p: Value> = Rc::new(RefCell::new(p)); (*p.borrow()).write(42); diff --git a/tests/unit/out/refcount/kruskal.rs b/tests/unit/out/refcount/kruskal.rs index e2e21b98..28978811 100644 --- a/tests/unit/out/refcount/kruskal.rs +++ b/tests/unit/out/refcount/kruskal.rs @@ -280,52 +280,14 @@ impl DisjointSet { } } } -impl ByteRepr for DisjointSet { - fn byte_size() -> usize { - 24 - } - fn to_bytes(&self, buf: &mut [u8]) { - (*self.rank.borrow()).to_bytes(&mut buf[0..8]); - (*self.parent.borrow()).to_bytes(&mut buf[8..16]); - (*self.n.borrow()).to_bytes(&mut buf[16..20]); - } - fn from_bytes(buf: &[u8]) -> Self { - Self { - rank: Rc::new(RefCell::new(>>>::from_bytes( - &buf[0..8], - ))), - parent: Rc::new(RefCell::new(>>>::from_bytes( - &buf[8..16], - ))), - n: Rc::new(RefCell::new(::from_bytes(&buf[16..20]))), - } - } -} +impl ByteRepr for DisjointSet {} #[derive(Default)] pub struct Graph { pub edges: Value>>>, pub V: Value, pub E: Value, } -impl ByteRepr for Graph { - fn byte_size() -> usize { - 16 - } - fn to_bytes(&self, buf: &mut [u8]) { - (*self.edges.borrow()).to_bytes(&mut buf[0..8]); - (*self.V.borrow()).to_bytes(&mut buf[8..12]); - (*self.E.borrow()).to_bytes(&mut buf[12..16]); - } - fn from_bytes(buf: &[u8]) -> Self { - Self { - edges: Rc::new(RefCell::new(>>>::from_bytes( - &buf[0..8], - ))), - V: Rc::new(RefCell::new(::from_bytes(&buf[8..12]))), - E: Rc::new(RefCell::new(::from_bytes(&buf[12..16]))), - } - } -} +impl ByteRepr for Graph {} pub fn MSTKruskal_2(graph: Ptr) -> f64 { ({ let _arr: Ptr>>> = (*graph.upgrade().deref()).edges.as_pointer(); diff --git a/tests/unit/out/refcount/push_emplace_back.rs b/tests/unit/out/refcount/push_emplace_back.rs index c6683ebb..c4309f6f 100644 --- a/tests/unit/out/refcount/push_emplace_back.rs +++ b/tests/unit/out/refcount/push_emplace_back.rs @@ -70,23 +70,7 @@ impl Clone for JPEGData { this } } -impl ByteRepr for JPEGData { - fn byte_size() -> usize { - 48 - } - fn to_bytes(&self, buf: &mut [u8]) { - (*self.com_data.borrow()).to_bytes(&mut buf[0..24]); - (*self.app_data.borrow()).to_bytes(&mut buf[24..48]); - } - fn from_bytes(buf: &[u8]) -> Self { - Self { - com_data: Rc::new(RefCell::new(>>>::from_bytes(&buf[0..24]))), - app_data: Rc::new(RefCell::new(>>>::from_bytes( - &buf[24..48], - ))), - } - } -} +impl ByteRepr for JPEGData {} pub fn push_param_0(dest: Ptr>>>) { let dest: Value>>>> = Rc::new(RefCell::new(dest)); ((*dest.borrow()).to_strong().as_pointer() as Ptr>>>).with_mut( diff --git a/tests/unit/out/refcount/typedef-anon-struct.rs b/tests/unit/out/refcount/typedef-anon-struct.rs index 80e81458..81475e04 100644 --- a/tests/unit/out/refcount/typedef-anon-struct.rs +++ b/tests/unit/out/refcount/typedef-anon-struct.rs @@ -47,19 +47,7 @@ impl Clone for Outer { this } } -impl ByteRepr for Outer { - fn byte_size() -> usize { - 24 - } - fn to_bytes(&self, buf: &mut [u8]) { - (*self.runs.borrow()).to_bytes(&mut buf[0..24]); - } - fn from_bytes(buf: &[u8]) -> Self { - Self { - runs: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), - } - } -} +impl ByteRepr for Outer {} pub fn main() { std::process::exit(main_0()); } diff --git a/tests/unit/out/refcount/unique_ptr.rs b/tests/unit/out/refcount/unique_ptr.rs index 9d4eb0eb..8f570b48 100644 --- a/tests/unit/out/refcount/unique_ptr.rs +++ b/tests/unit/out/refcount/unique_ptr.rs @@ -15,19 +15,7 @@ impl SafePointer { (*(*self.ptr.borrow_mut()).as_ref().unwrap().borrow_mut()).prefix_inc(); } } -impl ByteRepr for SafePointer { - fn byte_size() -> usize { - 8 - } - fn to_bytes(&self, buf: &mut [u8]) { - (*self.ptr.borrow()).to_bytes(&mut buf[0..8]); - } - fn from_bytes(buf: &[u8]) -> Self { - Self { - ptr: Rc::new(RefCell::new(>>::from_bytes(&buf[0..8]))), - } - } -} +impl ByteRepr for SafePointer {} #[derive(Default)] pub struct Pair { pub x: Value, diff --git a/tests/unit/out/refcount/unique_ptr_const_deref.rs b/tests/unit/out/refcount/unique_ptr_const_deref.rs index 8763aa17..ee468020 100644 --- a/tests/unit/out/refcount/unique_ptr_const_deref.rs +++ b/tests/unit/out/refcount/unique_ptr_const_deref.rs @@ -10,19 +10,7 @@ use std::rc::{Rc, Weak}; pub struct Holder { pub val: Value>>, } -impl ByteRepr for Holder { - fn byte_size() -> usize { - 8 - } - fn to_bytes(&self, buf: &mut [u8]) { - (*self.val.borrow()).to_bytes(&mut buf[0..8]); - } - fn from_bytes(buf: &[u8]) -> Self { - Self { - val: Rc::new(RefCell::new(>>::from_bytes(&buf[0..8]))), - } - } -} +impl ByteRepr for Holder {} pub fn read_val_0(h: Ptr) -> i32 { let h: Value> = Rc::new(RefCell::new(h)); return (*(*(*(*h.borrow()).upgrade().deref()).val.borrow()) diff --git a/tests/unit/out/refcount/unique_ptr_nested.rs b/tests/unit/out/refcount/unique_ptr_nested.rs index 73a07682..e1ad9181 100644 --- a/tests/unit/out/refcount/unique_ptr_nested.rs +++ b/tests/unit/out/refcount/unique_ptr_nested.rs @@ -39,19 +39,7 @@ impl ByteRepr for Inner { pub struct Outer { pub inner: Value>>, } -impl ByteRepr for Outer { - fn byte_size() -> usize { - 8 - } - fn to_bytes(&self, buf: &mut [u8]) { - (*self.inner.borrow()).to_bytes(&mut buf[0..8]); - } - fn from_bytes(buf: &[u8]) -> Self { - Self { - inner: Rc::new(RefCell::new(>>::from_bytes(&buf[0..8]))), - } - } -} +impl ByteRepr for Outer {} pub fn main() { std::process::exit(main_0()); } diff --git a/tests/unit/out/refcount/void_cast.rs b/tests/unit/out/refcount/void_cast.rs index f8b0af11..0933260f 100644 --- a/tests/unit/out/refcount/void_cast.rs +++ b/tests/unit/out/refcount/void_cast.rs @@ -22,19 +22,7 @@ impl Clone for NonTrivial { this } } -impl ByteRepr for NonTrivial { - fn byte_size() -> usize { - 24 - } - fn to_bytes(&self, buf: &mut [u8]) { - (*self.data.borrow()).to_bytes(&mut buf[0..24]); - } - fn from_bytes(buf: &[u8]) -> Self { - Self { - data: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), - } - } -} +impl ByteRepr for NonTrivial {} pub fn unused_ref_param_1(x: Ptr) { (*x.upgrade().deref()).clone(); } From 32d916a57bf0ec81dca34ee60e46fbd9da97a0fd Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 25 Jun 2026 22:20:47 +0100 Subject: [PATCH 10/15] Ignore unions in ByteRepr for now --- cpp2rust/converter/converter_lib.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 2eafb1c1..6332cdba 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -213,7 +213,7 @@ bool TypeImplementsByteRepr(clang::QualType qt) { return false; } if (rd->isUnion()) { - return true; + return false; } for (const auto *field : rd->fields()) { if (!TypeImplementsByteRepr(field->getType())) { From 96cd27033cdb1f1ee2adfc799e2760a22217a92a Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 25 Jun 2026 22:20:58 +0100 Subject: [PATCH 11/15] Update tests --- .../refcount/tag_vs_identifier_collision.rs | 26 ++++++++++++++++++- .../out/refcount/union_tagged_struct_arms.rs | 6 +++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/tests/unit/out/refcount/tag_vs_identifier_collision.rs b/tests/unit/out/refcount/tag_vs_identifier_collision.rs index eccceda4..bf14ce14 100644 --- a/tests/unit/out/refcount/tag_vs_identifier_collision.rs +++ b/tests/unit/out/refcount/tag_vs_identifier_collision.rs @@ -38,6 +38,9 @@ pub struct widget { pub mode: Value, } impl ByteRepr for widget { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.id.borrow()).to_bytes(&mut buf[0..4]); (*self.mode.borrow()).to_bytes(&mut buf[4..8]); @@ -55,6 +58,9 @@ pub struct point_struct { pub y: Value, } impl ByteRepr for point_struct { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); (*self.y.borrow()).to_bytes(&mut buf[4..8]); @@ -147,6 +153,9 @@ pub struct Inner { pub tag_field: Value, } impl ByteRepr for Inner { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.tag_field.borrow()).to_bytes(&mut buf[0..4]); } @@ -160,12 +169,27 @@ impl ByteRepr for Inner { pub struct Outer { pub field: Value, } -impl ByteRepr for Outer {} +impl ByteRepr for Outer { + fn byte_size() -> usize { + 4 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.field.borrow()).to_bytes(&mut buf[0..4]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + field: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + } + } +} #[derive(Default)] pub struct Inner_struct { pub typedef_field: Value, } impl ByteRepr for Inner_struct { + fn byte_size() -> usize { + 4 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.typedef_field.borrow()).to_bytes(&mut buf[0..4]); } diff --git a/tests/unit/out/refcount/union_tagged_struct_arms.rs b/tests/unit/out/refcount/union_tagged_struct_arms.rs index 37417848..4155c690 100644 --- a/tests/unit/out/refcount/union_tagged_struct_arms.rs +++ b/tests/unit/out/refcount/union_tagged_struct_arms.rs @@ -47,6 +47,9 @@ pub struct anon_2 { pub step: Value, } impl ByteRepr for anon_2 { + fn byte_size() -> usize { + 16 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.lo.borrow()).to_bytes(&mut buf[0..4]); (*self.hi.borrow()).to_bytes(&mut buf[4..8]); @@ -71,6 +74,9 @@ pub struct anon_3 { pub width: Value, } impl ByteRepr for anon_3 { + fn byte_size() -> usize { + 40 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.lo.borrow()).to_bytes(&mut buf[0..8]); (*self.hi.borrow()).to_bytes(&mut buf[8..16]); From 34020423ab50e9a69ad93c6d5d5e849d69fe472e Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Tue, 23 Jun 2026 16:03:03 +0100 Subject: [PATCH 12/15] Memcpy a poitner to a struct through ErasedPtr --- libcc2rs/src/fn_ptr.rs | 16 +++----- libcc2rs/src/rc.rs | 90 +++++++++--------------------------------- 2 files changed, 23 insertions(+), 83 deletions(-) diff --git a/libcc2rs/src/fn_ptr.rs b/libcc2rs/src/fn_ptr.rs index 2ccc150e..e7152279 100644 --- a/libcc2rs/src/fn_ptr.rs +++ b/libcc2rs/src/fn_ptr.rs @@ -6,7 +6,7 @@ use std::marker::PhantomData; use std::ops::Deref; use std::rc::Rc; -use crate::rc::{AnyPtr, ErasedPtr}; +use crate::rc::{AnyPtr, ErasedPtr, Ptr}; use crate::reinterpret::ByteRepr; pub trait FnAddr { @@ -146,20 +146,14 @@ impl Eq for FnPtr {} impl ByteRepr for FnPtr {} impl ErasedPtr for FnPtr { - fn pointee_type_id(&self) -> TypeId { - TypeId::of::() - } - fn memcpy(&self, _src: &dyn ErasedPtr, _len: usize) { - panic!("memcpy not supported on fn pointer"); + fn as_bytes(&self) -> Ptr { + panic!("byte view not supported on fn pointer"); } fn as_any(&self) -> &dyn Any { self } - fn equals(&self, other: &dyn ErasedPtr) -> Option { - if self.pointee_type_id() != other.pointee_type_id() { - return None; - } - other.as_any().downcast_ref::>().map(|o| self == o) + fn equals(&self, other: &dyn ErasedPtr) -> bool { + other.as_any().downcast_ref::>() == Some(self) } fn is_null(&self) -> bool { FnPtr::is_null(self) diff --git a/libcc2rs/src/rc.rs b/libcc2rs/src/rc.rs index ac09c80c..ce8bf501 100644 --- a/libcc2rs/src/rc.rs +++ b/libcc2rs/src/rc.rs @@ -1042,49 +1042,33 @@ impl Ptr { } pub(crate) trait ErasedPtr: std::any::Any { - fn pointee_type_id(&self) -> std::any::TypeId; - fn memcpy(&self, src: &dyn ErasedPtr, len: usize); + fn as_bytes(&self) -> Ptr; fn as_any(&self) -> &dyn std::any::Any; - fn equals(&self, other: &dyn ErasedPtr) -> Option; + fn equals(&self, other: &dyn ErasedPtr) -> bool; fn is_null(&self) -> bool; } +impl PartialEq for dyn ErasedPtr { + fn eq(&self, other: &Self) -> bool { + self.equals(other) + } +} + impl ErasedPtr for Ptr where T: ByteRepr + 'static, Ptr: PartialEq, { - fn pointee_type_id(&self) -> std::any::TypeId { - std::any::TypeId::of::() - } - - fn memcpy(&self, src: &dyn ErasedPtr, len: usize) { - if self.pointee_type_id() != src.pointee_type_id() { - panic!("memcpy: type mismatch"); - } - let src_ptr = src - .as_any() - .downcast_ref::>() - .expect("memcpy: downcast to Ptr failed"); - let dst_bytes: Ptr = self.reinterpret_cast(); - let src_bytes: Ptr = src_ptr.reinterpret_cast(); - dst_bytes.memcpy(&src_bytes, len); + fn as_bytes(&self) -> Ptr { + self.reinterpret_cast::() } fn as_any(&self) -> &dyn std::any::Any { self } - fn equals(&self, other: &dyn ErasedPtr) -> Option { - if self.pointee_type_id() != other.pointee_type_id() { - return None; - } - - if let Some(other_ptr) = other.as_any().downcast_ref::>() { - return Some(self == other_ptr); - } - - None + fn equals(&self, other: &dyn ErasedPtr) -> bool { + other.as_any().downcast_ref::>() == Some(self) } fn is_null(&self) -> bool { @@ -1118,66 +1102,28 @@ impl AnyPtr { } self.ptr.as_any().downcast_ref::>().cloned() } - - pub fn reinterpret_cast(&self) -> Ptr { - macro_rules! try_src { - ($ty:ty) => {{ - if let Some(p) = self.cast::<$ty>() { - return p.reinterpret_cast::(); - } - if let Some(pv) = self.cast::>() { - return pv.reinterpret_cast::(); - } - }}; - } - - try_src!(u8); - try_src!(i8); - try_src!(u16); - try_src!(i16); - try_src!(u32); - try_src!(i32); - try_src!(u64); - try_src!(i64); - try_src!(usize); - try_src!(isize); - - panic!("reinterpret_cast: unsupported AnyPtr source"); - } } impl PartialEq for AnyPtr { fn eq(&self, other: &Self) -> bool { - let lhs: &dyn ErasedPtr = self.ptr.as_ref(); - let rhs: &dyn ErasedPtr = other.ptr.as_ref(); - - lhs.equals(rhs).unwrap_or_default() + *self.ptr == *other.ptr } } impl AnyPtr { pub fn memcpy(&self, src: &AnyPtr, len: usize) { - let dst_erased = &*self.ptr; - let src_erased = &*src.ptr; - - if dst_erased.pointee_type_id() == src_erased.pointee_type_id() { - dst_erased.memcpy(src_erased, len); - return; - } - - let dst_u8: Ptr = self.reinterpret_cast(); - let src_u8: Ptr = src.reinterpret_cast(); + let dst_u8 = self.ptr.as_bytes(); + let src_u8 = src.ptr.as_bytes(); dst_u8.memcpy(&src_u8, len); } pub fn memset(&self, value: u8, num: usize) { - let dst_u8: Ptr = self.reinterpret_cast(); - dst_u8.memset(value, num); + self.ptr.as_bytes().memset(value, num); } pub fn memcmp(&self, other: &AnyPtr, len: usize) -> i32 { - let a: Ptr = self.reinterpret_cast(); - let b: Ptr = other.reinterpret_cast(); + let a = self.ptr.as_bytes(); + let b = other.ptr.as_bytes(); a.memcmp(&b, len) } } From fb7f030fe5e0a90cd9a6318d64ac1c6c171882dc Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 25 Jun 2026 14:49:53 +0100 Subject: [PATCH 13/15] Add memcpy_struct_bytes test --- tests/unit/memcpy_struct_bytes.c | 23 ++++++++ .../unit/out/refcount/memcpy_struct_bytes.rs | 55 +++++++++++++++++++ tests/unit/out/unsafe/memcpy_struct_bytes.rs | 47 ++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 tests/unit/memcpy_struct_bytes.c create mode 100644 tests/unit/out/refcount/memcpy_struct_bytes.rs create mode 100644 tests/unit/out/unsafe/memcpy_struct_bytes.rs diff --git a/tests/unit/memcpy_struct_bytes.c b/tests/unit/memcpy_struct_bytes.c new file mode 100644 index 00000000..ae767639 --- /dev/null +++ b/tests/unit/memcpy_struct_bytes.c @@ -0,0 +1,23 @@ +#include +#include +#include + +struct point { + int32_t x; + int32_t y; +}; + +int main(void) { + struct point src = {3, 7}; + + unsigned char buf[sizeof(struct point)]; + memcpy(buf, &src, sizeof(buf)); + + struct point dst; + memcpy(&dst, buf, sizeof(dst)); + + assert(dst.x == 3); + assert(dst.y == 7); + + return 0; +} diff --git a/tests/unit/out/refcount/memcpy_struct_bytes.rs b/tests/unit/out/refcount/memcpy_struct_bytes.rs new file mode 100644 index 00000000..ada7f67a --- /dev/null +++ b/tests/unit/out/refcount/memcpy_struct_bytes.rs @@ -0,0 +1,55 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +#[derive(Default)] +pub struct point { + pub x: Value, + pub y: Value, +} +impl ByteRepr for point { + fn to_bytes(&self, buf: &mut [u8]) { + (*self.x.borrow()).to_bytes(&mut buf[0..4]); + (*self.y.borrow()).to_bytes(&mut buf[4..8]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + x: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + y: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + } + } +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let src: Value = Rc::new(RefCell::new(point { + x: Rc::new(RefCell::new(3)), + y: Rc::new(RefCell::new(7)), + })); + let buf: Value> = Rc::new(RefCell::new( + (0..8).map(|_| ::default()).collect::>(), + )); + { + ((buf.as_pointer() as Ptr) as Ptr).to_any().memcpy( + &((src.as_pointer()) as Ptr).to_any(), + ::std::mem::size_of::<[u8; 8]>() as usize, + ); + ((buf.as_pointer() as Ptr) as Ptr).to_any().clone() + }; + let dst: Value = >::default(); + { + ((dst.as_pointer()) as Ptr).to_any().memcpy( + &((buf.as_pointer() as Ptr) as Ptr).to_any(), + ::std::mem::size_of::() as usize, + ); + ((dst.as_pointer()) as Ptr).to_any().clone() + }; + assert!(((((*(*dst.borrow()).x.borrow()) == 3) as i32) != 0)); + assert!(((((*(*dst.borrow()).y.borrow()) == 7) as i32) != 0)); + return 0; +} diff --git a/tests/unit/out/unsafe/memcpy_struct_bytes.rs b/tests/unit/out/unsafe/memcpy_struct_bytes.rs new file mode 100644 index 00000000..110b0a87 --- /dev/null +++ b/tests/unit/out/unsafe/memcpy_struct_bytes.rs @@ -0,0 +1,47 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct point { + pub x: i32, + pub y: i32, +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut src: point = point { x: 3, y: 7 }; + let mut buf: [u8; 8] = [0_u8; 8]; + { + if ::std::mem::size_of::<[u8; 8]>() != 0 { + ::std::ptr::copy_nonoverlapping( + ((&mut src as *mut point) as *const point as *const ::libc::c_void), + (buf.as_mut_ptr() as *mut u8 as *mut ::libc::c_void), + ::std::mem::size_of::<[u8; 8]>() as usize, + ) + } + (buf.as_mut_ptr() as *mut u8 as *mut ::libc::c_void) + }; + let mut dst: point = ::default(); + { + if ::std::mem::size_of::() != 0 { + ::std::ptr::copy_nonoverlapping( + (buf.as_mut_ptr() as *const u8 as *const ::libc::c_void), + ((&mut dst as *mut point) as *mut point as *mut ::libc::c_void), + ::std::mem::size_of::() as usize, + ) + } + ((&mut dst as *mut point) as *mut point as *mut ::libc::c_void) + }; + assert!(((((dst.x) == (3)) as i32) != 0)); + assert!(((((dst.y) == (7)) as i32) != 0)); + return 0; +} From e4bb83ea93687b3485e1280cfa1ee756379dfb13 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 25 Jun 2026 17:49:02 +0100 Subject: [PATCH 14/15] Update tests --- tests/unit/out/refcount/memcpy_struct_bytes.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/unit/out/refcount/memcpy_struct_bytes.rs b/tests/unit/out/refcount/memcpy_struct_bytes.rs index ada7f67a..d233b346 100644 --- a/tests/unit/out/refcount/memcpy_struct_bytes.rs +++ b/tests/unit/out/refcount/memcpy_struct_bytes.rs @@ -12,6 +12,9 @@ pub struct point { pub y: Value, } impl ByteRepr for point { + fn byte_size() -> usize { + 8 + } fn to_bytes(&self, buf: &mut [u8]) { (*self.x.borrow()).to_bytes(&mut buf[0..4]); (*self.y.borrow()).to_bytes(&mut buf[4..8]); @@ -45,7 +48,7 @@ fn main_0() -> i32 { { ((dst.as_pointer()) as Ptr).to_any().memcpy( &((buf.as_pointer() as Ptr) as Ptr).to_any(), - ::std::mem::size_of::() as usize, + 8usize as usize, ); ((dst.as_pointer()) as Ptr).to_any().clone() }; From 48d69080873dceca3afe4fbcc40a73121690eec0 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 29 Jun 2026 14:08:13 +0100 Subject: [PATCH 15/15] Trigger CI