From d829a3d8be070c64a43c3ebf70ec50c3ca2fd733 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Mon, 25 Nov 2024 15:15:55 +0200 Subject: [PATCH 01/13] ManagedVecItem payload refactor - several attempts --- .../esdt_token_payment_multi_value.rs | 5 +- .../managed/wrapped/esdt_token_payment.rs | 4 + .../types/managed/wrapped/managed_option.rs | 4 + .../types/managed/wrapped/managed_vec_item.rs | 56 ++++++- .../wrapped/managed_vec_item_nested_tuple.rs | 63 +++++++ .../wrapped/managed_vec_item_payload.rs | 155 +++++++++++++++++- .../base/src/types/managed/wrapped/mod.rs | 2 +- .../derive/src/managed_vec_item_derive.rs | 8 + .../src/api/impl_vh/debug_handle_vh.rs | 4 + 9 files changed, 295 insertions(+), 6 deletions(-) diff --git a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs index 1ebc5d5fe7..4eb6fc60d8 100644 --- a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs +++ b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs @@ -44,11 +44,14 @@ impl ManagedVecItem for EsdtTokenPaymentMultiValue { const SKIPS_RESERIALIZATION: bool = EsdtTokenPayment::::SKIPS_RESERIALIZATION; type Ref<'a> = Self; - #[inline] fn from_byte_reader(reader: Reader) -> Self { EsdtTokenPayment::from_byte_reader(reader).into() } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + EsdtTokenPayment::read_from_payload(payload).into() + } + #[inline] unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, diff --git a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs index cf2ccf0ceb..a92a9cbe16 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs @@ -205,6 +205,10 @@ impl ManagedVecItem for EsdtTokenPayment { } } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + todo!() + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index 767592363d..ae77c6bc92 100644 --- a/framework/base/src/types/managed/wrapped/managed_option.rs +++ b/framework/base/src/types/managed/wrapped/managed_option.rs @@ -208,6 +208,10 @@ where Self::new_with_handle(handle) } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + Self::new_with_handle(use_raw_handle(i32::read_from_payload(payload))) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index a883d991e3..8c06da18c3 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -3,14 +3,14 @@ use core::borrow::Borrow; use multiversx_chain_core::types::{EsdtLocalRole, EsdtTokenType}; use crate::{ - api::ManagedTypeApi, + api::{use_raw_handle, ManagedTypeApi}, types::{ BigInt, BigUint, EllipticCurve, ManagedAddress, ManagedBuffer, ManagedByteArray, ManagedRef, ManagedType, ManagedVec, TokenIdentifier, }, }; -use super::{ManagedVecItemNestedTuple, ManagedVecItemPayload, ManagedVecItemPayloadBuffer}; +use super::{ManagedVecItemNestedTuple, ManagedVecItemNestedTupleSplit, ManagedVecItemPayload, ManagedVecItemPayloadBuffer}; /// Types that implement this trait can be items inside a `ManagedVec`. /// All these types need a payload, i.e a representation that gets stored @@ -44,6 +44,8 @@ pub trait ManagedVecItem: 'static { /// Parses given bytes as a an owned object. fn from_byte_reader(reader: Reader) -> Self; + fn read_from_payload(payload: &Self::PAYLOAD) -> Self; + /// Parses given bytes as a representation of the object, either owned, or a reference. /// /// # Safety @@ -71,11 +73,17 @@ macro_rules! impl_int { type PAYLOAD = ManagedVecItemPayloadBuffer<$payload_size>; const SKIPS_RESERIALIZATION: bool = true; type Ref<'a> = Self; + fn from_byte_reader(mut reader: Reader) -> Self { let mut arr: [u8; $payload_size] = [0u8; $payload_size]; reader(&mut arr[..]); $ty::from_be_bytes(arr) } + + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + $ty::from_be_bytes(payload.buffer) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -107,6 +115,10 @@ impl ManagedVecItem for usize { u32::from_be_bytes(arr) as usize } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + u32::read_from_payload(payload) as usize + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -128,6 +140,10 @@ impl ManagedVecItem for bool { u8::from_byte_reader(reader) > 0 } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + u8::read_from_payload(payload) > 0 + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -164,6 +180,17 @@ where } } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + // let (p1, (p2, ())) = <(u8, (T, ()))>::split_all(payload); + + // let disc = u8::read_from_payload(p1); + // let x = split_payload(payload); + // Self::PAYLOAD::spli + todo!() + // let (disc_payload, t_payload) = payload.split::<1>(); + // let x = payload; + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -195,6 +222,11 @@ macro_rules! impl_managed_type { unsafe { $ty::from_handle(handle) } } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + let handle = use_raw_handle(i32::read_from_payload(payload)); + unsafe { Self::from_handle(handle) } + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -230,6 +262,11 @@ where unsafe { Self::from_handle(handle) } } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + let handle = use_raw_handle(i32::read_from_payload(payload)); + unsafe { Self::from_handle(handle) } + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -259,6 +296,11 @@ where unsafe { Self::from_handle(handle) } } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + let handle = use_raw_handle(i32::read_from_payload(payload)); + unsafe { Self::from_handle(handle) } + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -283,6 +325,10 @@ impl ManagedVecItem for EsdtTokenType { arr[0].into() } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + u8::read_from_payload(payload).into() + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -295,7 +341,7 @@ impl ManagedVecItem for EsdtTokenType { } impl ManagedVecItem for EsdtLocalRole { - type PAYLOAD = ManagedVecItemPayloadBuffer<1>; + type PAYLOAD = ManagedVecItemPayloadBuffer<2>; const SKIPS_RESERIALIZATION: bool = false; // TODO: might be ok to be true, but needs testing type Ref<'a> = Self; @@ -303,6 +349,10 @@ impl ManagedVecItem for EsdtLocalRole { u16::from_byte_reader(reader).into() } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + u16::read_from_payload(payload).into() + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs index 3a25bf4993..45e6a8d820 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs @@ -5,11 +5,35 @@ use super::{ /// Syntactic sugar, that allows us to more easily represent composite payloads as nested tuples. pub trait ManagedVecItemNestedTuple { type PAYLOAD: ManagedVecItemPayload; + type Split1: ManagedVecItemPayload; + type Split2: ManagedVecItemPayload; + + fn split_payload(payload: &Self::PAYLOAD) -> (&Self::Split1, &Self::Split2); +} + +pub trait ManagedVecItemNestedTupleSplit<'a>: ManagedVecItemNestedTuple { + type S; + + fn split_all(payload: &'a Self::PAYLOAD) -> Self::S; } /// End of the list. impl ManagedVecItemNestedTuple for () { type PAYLOAD = ManagedVecItemEmptyPayload; + type Split1 = ManagedVecItemEmptyPayload; + type Split2 = ManagedVecItemEmptyPayload; + + fn split_payload(_payload: &Self::PAYLOAD) -> (&Self::Split1, &Self::Split2) { + (&ManagedVecItemEmptyPayload, &ManagedVecItemEmptyPayload) + } +} + +impl<'a> ManagedVecItemNestedTupleSplit<'a> for () { + type S = (); + + fn split_all(_payload: &'a Self::PAYLOAD) -> Self::S { + () + } } impl ManagedVecItemNestedTuple for (Head, Tail) @@ -19,8 +43,47 @@ where Head::PAYLOAD: ManagedVecItemPayloadAdd, { type PAYLOAD = >::Output; + type Split1 = ::PAYLOAD; + type Split2 = ::PAYLOAD; + + fn split_payload(payload: &Self::PAYLOAD) -> (&Self::Split1, &Self::Split2) { + Head::PAYLOAD::split_from_add(payload) + } +} + +impl<'a, Head, Tail> ManagedVecItemNestedTupleSplit<'a> for (Head, Tail) +where + Head: ManagedVecItem, + Tail: ManagedVecItemNestedTupleSplit<'a>, + Head::PAYLOAD: ManagedVecItemPayloadAdd, + Tail::PAYLOAD: 'a, +{ + type S = (&'a Head::PAYLOAD, Tail::S); + + fn split_all(payload: &'a Self::PAYLOAD) -> Self::S { + let (hp, tp) = Head::PAYLOAD::split_from_add(payload); + (hp, Tail::split_all(tp)) + } } +// pub fn split_payload( +// payload: &<(Head, Tail) as ManagedVecItemNestedTuple>::PAYLOAD, +// ) -> (&Head::PAYLOAD, &Tail::PAYLOAD) +// where +// Head: ManagedVecItem, +// Tail: ManagedVecItemNestedTuple, +// Head::PAYLOAD: ManagedVecItemPayloadAdd, +// // (Head, Tail): ManagedVecItemNestedTuple, +// { +// >::split_from_add(payload) +// // <(Head, Tail) as ManagedVecItemNestedTuple>::PAYLOAD as +// // unsafe { +// // let ptr1 = payload.buffer.as_ptr(); +// // let ptr2 = ptr1.offset($dec1 as isize); +// // (core::mem::transmute(ptr1), core::mem::transmute(ptr2)) +// // } +// } + #[cfg(test)] pub mod tests { use super::*; diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs index 07adc31a08..4fcc20d9d3 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs @@ -1,3 +1,5 @@ +use core::marker::PhantomData; + /// Describes the binary represetnation of a ManagedVecItem. /// /// It is always an array that can be allocated directly on stack. @@ -35,8 +37,9 @@ impl ManagedVecItemPayload for ManagedVecItemEmptyPayload { } /// The main ManagedVecItemPayload implementation. Uses an array in its implementation. +#[repr(transparent)] pub struct ManagedVecItemPayloadBuffer { - buffer: [u8; N], + pub buffer: [u8; N], } impl ManagedVecItemPayload for ManagedVecItemPayloadBuffer { @@ -57,6 +60,83 @@ impl ManagedVecItemPayload for ManagedVecItemPayloadBuffer { } } +#[repr(transparent)] +pub struct ManagedVecItemPayloadConcat +where + P1: ManagedVecItemPayload, + P2: ManagedVecItemPayload, + P1: ManagedVecItemPayloadAdd, +{ + _phantom_1: PhantomData, + _phantom_2: PhantomData, + buffer: >::Output, +} + +impl ManagedVecItemPayload for ManagedVecItemPayloadConcat +where + P1: ManagedVecItemPayload, + P2: ManagedVecItemPayload, + P1: ManagedVecItemPayloadAdd, +{ + fn new_buffer() -> Self { + ManagedVecItemPayloadConcat { + _phantom_1: PhantomData, + _phantom_2: PhantomData, + buffer: ManagedVecItemPayload::new_buffer(), + } + } + + fn payload_size() -> usize { + >::Output::payload_size() + } + + fn payload_slice(&self) -> &[u8] { + self.buffer.payload_slice() + } + + fn payload_slice_mut(&mut self) -> &mut [u8] { + self.buffer.payload_slice_mut() + } +} + +impl ManagedVecItemPayloadConcat +where + P1: ManagedVecItemPayload, + P2: ManagedVecItemPayload, + P1: ManagedVecItemPayloadAdd, +{ +} + +impl ManagedVecItemPayloadAdd> for P0 +where + P0: ManagedVecItemPayload, + P1: ManagedVecItemPayload, + P2: ManagedVecItemPayload, + P1: ManagedVecItemPayloadAdd, + P0: ManagedVecItemPayloadAdd<>::Output>, +{ + type Output = ManagedVecItemPayloadConcat>; + + fn split_from_add(payload: &Self::Output) -> (&Self, &ManagedVecItemPayloadConcat) { + todo!() + } + + + + // fn split_from_add( + // payload: &ManagedVecItemPayloadBuffer<$result_add>, + // ) -> ( + // &ManagedVecItemPayloadBuffer<$dec1>, + // &ManagedVecItemPayloadBuffer<$dec2>, + // ) { + // unsafe { + // let ptr1 = payload.buffer.as_ptr(); + // let ptr2 = ptr1.offset($dec1 as isize); + // (core::mem::transmute(ptr1), core::mem::transmute(ptr2)) + // } + // } +} + /// Describes concatantion of smaller payloads into a larger one. /// /// There is no runtime implementation, just a type-level addition. @@ -67,12 +147,39 @@ where Rhs: ManagedVecItemPayload, { type Output: ManagedVecItemPayload; + + fn split_from_add(payload: &Self::Output) -> (&Self, &Rhs); } impl ManagedVecItemPayloadAdd for ManagedVecItemPayloadBuffer { type Output = Self; + + fn split_from_add(payload: &Self::Output) -> (&Self, &ManagedVecItemEmptyPayload) { + (payload, &ManagedVecItemEmptyPayload) + } +} + +pub trait ManagedVecItemPayloadSplit: ManagedVecItemPayload { + type P1: ManagedVecItemPayload; + type P2: ManagedVecItemPayload; + + fn split_impl(&self) -> (&Self::P1, &Self::P2); +} + +impl ManagedVecItemPayloadBuffer { + pub fn split_me( + &self, + ) -> ( + &>::P1, + &>::P2, + ) + where + Self: ManagedVecItemPayloadSplit, + { + ManagedVecItemPayloadSplit::::split_impl(self) + } } /// Replaces a const generic expression. @@ -84,10 +191,56 @@ macro_rules! payload_add { for ManagedVecItemPayloadBuffer<$dec1> { type Output = ManagedVecItemPayloadBuffer<$result_add>; + + fn split_from_add( + payload: &ManagedVecItemPayloadBuffer<$result_add>, + ) -> ( + &ManagedVecItemPayloadBuffer<$dec1>, + &ManagedVecItemPayloadBuffer<$dec2>, + ) { + unsafe { + let ptr1 = payload.buffer.as_ptr(); + let ptr2 = ptr1.offset($dec1 as isize); + (core::mem::transmute(ptr1), core::mem::transmute(ptr2)) + } + } + } + + impl ManagedVecItemPayloadSplit<$dec1> for ManagedVecItemPayloadBuffer<$result_add> { + type P1 = ManagedVecItemPayloadBuffer<$dec1>; + type P2 = ManagedVecItemPayloadBuffer<$dec2>; + + fn split_impl( + &self, + ) -> ( + &ManagedVecItemPayloadBuffer<$dec1>, + &ManagedVecItemPayloadBuffer<$dec2>, + ) { + unsafe { + let ptr1 = self.buffer.as_ptr(); + let ptr2 = ptr1.offset($dec1 as isize); + (core::mem::transmute(ptr1), core::mem::transmute(ptr2)) + } + } } }; } +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn payload_split() { + let payload = ManagedVecItemPayloadBuffer { + buffer: [1, 2, 3, 4, 5], + }; + let (p1, p2) = payload.split_me::<3>(); + assert_eq!(p1.buffer, [1, 2, 3]); + assert_eq!(p2.buffer, [4, 5]); + } +} + payload_add!(1usize, 1usize, 2usize); payload_add!(1usize, 2usize, 3usize); payload_add!(1usize, 3usize, 4usize); diff --git a/framework/base/src/types/managed/wrapped/mod.rs b/framework/base/src/types/managed/wrapped/mod.rs index 37849e0b6c..f4db4e5212 100644 --- a/framework/base/src/types/managed/wrapped/mod.rs +++ b/framework/base/src/types/managed/wrapped/mod.rs @@ -47,7 +47,7 @@ pub use managed_ref::ManagedRef; pub use managed_ref_mut::ManagedRefMut; pub use managed_vec::ManagedVec; pub use managed_vec_item::ManagedVecItem; -pub use managed_vec_item_nested_tuple::ManagedVecItemNestedTuple; +pub use managed_vec_item_nested_tuple::{ManagedVecItemNestedTuple, ManagedVecItemNestedTupleSplit}; pub use managed_vec_item_payload::*; pub use managed_vec_owned_iter::ManagedVecOwnedIterator; pub use managed_vec_ref::ManagedVecRef; diff --git a/framework/derive/src/managed_vec_item_derive.rs b/framework/derive/src/managed_vec_item_derive.rs index 17c07f21a4..c0525ee0d5 100644 --- a/framework/derive/src/managed_vec_item_derive.rs +++ b/framework/derive/src/managed_vec_item_derive.rs @@ -133,6 +133,10 @@ fn enum_derive(data_enum: &syn::DataEnum, ast: &syn::DeriveInput) -> TokenStream } } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + todo!() + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>(reader: Reader) -> Self::Ref<'a> { Self::from_byte_reader(reader) } @@ -176,6 +180,10 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token } } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + todo!() + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>(reader: Reader) -> Self::Ref<'a> { Self::from_byte_reader(reader) } diff --git a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs index 99dc7c6e87..c60df36991 100644 --- a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs +++ b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs @@ -87,6 +87,10 @@ impl ManagedVecItem for DebugHandle { use_raw_handle(RawHandle::from_byte_reader(reader)) } + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + use_raw_handle(RawHandle::read_from_payload(payload)) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { From bb59ac16455067aaf3c8d177080583f997fbfc07 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 01:15:13 +0200 Subject: [PATCH 02/13] ManagedVecItem payload refactor - more attempts, read_from_payload impl --- .../src/types/managed/wrapped/managed_vec.rs | 18 ++-- .../types/managed/wrapped/managed_vec_item.rs | 101 ++++++++++++++++-- .../wrapped/managed_vec_item_nested_tuple.rs | 18 ++++ .../wrapped/managed_vec_item_payload.rs | 69 +++++++++--- .../managed/wrapped/managed_vec_owned_iter.rs | 16 +-- .../base/src/types/managed/wrapped/mod.rs | 6 +- .../derive/src/managed_vec_item_derive.rs | 32 +++++- 7 files changed, 215 insertions(+), 45 deletions(-) diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index d3212e4d03..475bc300d3 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -1,4 +1,4 @@ -use super::EncodedManagedVecItem; +use super::{EncodedManagedVecItem, ManagedVecItemPayload}; use crate::{ abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName}, api::{ErrorApiImpl, InvalidSliceError, ManagedTypeApi}, @@ -187,15 +187,15 @@ where pub(super) unsafe fn get_unsafe(&self, index: usize) -> T { let byte_index = index * T::payload_size(); - let mut load_result = Ok(()); - let result = T::from_byte_reader(|dest_slice| { - load_result = self.buffer.load_slice(byte_index, dest_slice); - }); - - match load_result { - Ok(_) => result, - Err(_) => M::error_api_impl().signal_error(INDEX_OUT_OF_RANGE_MSG), + let mut payload = T::PAYLOAD::new_buffer(); + if self + .buffer + .load_slice(byte_index, payload.payload_slice_mut()) + .is_err() + { + M::error_api_impl().signal_error(INDEX_OUT_OF_RANGE_MSG); } + T::read_from_payload(&payload) } pub fn set(&mut self, index: usize, item: T) -> Result<(), InvalidSliceError> { diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 8c06da18c3..484a106d41 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -10,7 +10,10 @@ use crate::{ }, }; -use super::{ManagedVecItemNestedTuple, ManagedVecItemNestedTupleSplit, ManagedVecItemPayload, ManagedVecItemPayloadBuffer}; +use super::{ + ManagedVecItemEmptyPayload, ManagedVecItemNestedTuple, ManagedVecItemNestedTupleSplit, + ManagedVecItemPayload, ManagedVecItemPayloadAdd, ManagedVecItemPayloadBuffer, +}; /// Types that implement this trait can be items inside a `ManagedVec`. /// All these types need a payload, i.e a representation that gets stored @@ -67,6 +70,16 @@ pub trait ManagedVecItem: 'static { fn into_byte_writer R>(self, writer: Writer) -> R; } +pub unsafe fn managed_vec_item_read_from_payload_index(payload: &P, index: &mut usize) -> T +where + T: ManagedVecItem, + P: ManagedVecItemPayload, +{ + let value = T::read_from_payload(payload.slice_unchecked(*index)); + *index += T::PAYLOAD::payload_size(); + value +} + macro_rules! impl_int { ($ty:ident, $payload_size:expr) => { impl ManagedVecItem for $ty { @@ -161,9 +174,12 @@ impl ManagedVecItem for bool { impl ManagedVecItem for Option where (u8, (T, ())): ManagedVecItemNestedTuple, + ManagedVecItemPayloadBuffer<1>: ManagedVecItemPayloadAdd, T: ManagedVecItem, { - type PAYLOAD = <(u8, (T, ())) as ManagedVecItemNestedTuple>::PAYLOAD; + // type PAYLOAD = <(u8, (T, ())) as ManagedVecItemNestedTuple>::PAYLOAD; + type PAYLOAD = as ManagedVecItemPayloadAdd>::Output; + // type PAYLOAD = EquivPayload<(u8, T)>; const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = Self; @@ -182,13 +198,26 @@ where fn read_from_payload(payload: &Self::PAYLOAD) -> Self { // let (p1, (p2, ())) = <(u8, (T, ()))>::split_all(payload); - + + // let (p1, p2) = as ManagedVecItemPayloadAdd< + // T::PAYLOAD, + // >>::split_from_add(payload); + // let disc = u8::read_from_payload(p1); - // let x = split_payload(payload); - // Self::PAYLOAD::spli - todo!() - // let (disc_payload, t_payload) = payload.split::<1>(); - // let x = payload; + // if disc == 0 { + // None + // } else { + // Some(T::read_from_payload(p2)) + // } + + unsafe { + let disc = u8::read_from_payload(payload.slice_unchecked(0)); + if disc == 0 { + None + } else { + Some(T::read_from_payload(payload.slice_unchecked(1))) + } + } } unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( @@ -363,3 +392,59 @@ impl ManagedVecItem for EsdtLocalRole { ::into_byte_writer(self.as_u16(), writer) } } + +impl ManagedVecItem for () { + type PAYLOAD = ManagedVecItemEmptyPayload; + + const SKIPS_RESERIALIZATION: bool = true; + + type Ref<'a> = Self; + + fn from_byte_reader(reader: Reader) -> Self { + () + } + + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + () + } + + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( + _reader: Reader, + ) -> Self::Ref<'a> { + () + } + + fn into_byte_writer R>(self, writer: Writer) -> R { + todo!() + } +} + +impl ManagedVecItem for (Head, Tail) +where + Head: ManagedVecItem + 'static, + Tail: ManagedVecItem + 'static, +{ + type PAYLOAD = ManagedVecItemEmptyPayload; + + const SKIPS_RESERIALIZATION: bool = true; + + type Ref<'a> = Self; + + fn from_byte_reader(reader: Reader) -> Self { + todo!() + } + + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + todo!() + } + + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( + reader: Reader, + ) -> Self::Ref<'a> { + todo!() + } + + fn into_byte_writer R>(self, writer: Writer) -> R { + todo!() + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs index 45e6a8d820..7c64920cf3 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs @@ -86,6 +86,8 @@ where #[cfg(test)] pub mod tests { + use crate::types::ManagedVecItemPayloadBuffer; + use super::*; #[test] @@ -100,4 +102,20 @@ pub mod tests { fn assert_payload_size(expected_size: usize) { assert_eq!(N::PAYLOAD::payload_size(), expected_size); } + + #[test] + fn split_all_test() { + let p = ManagedVecItemPayloadBuffer::new_buffer(); + let (p1, (p2, ())) = <(u16, (u32, ()))>::split_all(&p); + } + + // fn split_all_t() + // where + // T: ManagedVecItem, + // ManagedVecItemPayloadBuffer<1>: ManagedVecItemPayloadAdd, + // (u16, (T, ())): ManagedVecItemNestedTuple, + // { + // let p = ManagedVecItemPayloadBuffer::new_buffer(); + // let (p1, (p2, ())) = <(u16, (T, ()))>::split_all(&p); + // } } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs index 4fcc20d9d3..ba2d7e1296 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs @@ -1,5 +1,7 @@ use core::marker::PhantomData; +use super::ManagedVecItem; + /// Describes the binary represetnation of a ManagedVecItem. /// /// It is always an array that can be allocated directly on stack. @@ -11,6 +13,8 @@ pub trait ManagedVecItemPayload { fn payload_slice(&self) -> &[u8]; fn payload_slice_mut(&mut self) -> &mut [u8]; + + unsafe fn slice_unchecked(&self, index: usize) -> &S; } /// Empty ManagedVecItem. @@ -34,6 +38,10 @@ impl ManagedVecItemPayload for ManagedVecItemEmptyPayload { fn payload_slice_mut(&mut self) -> &mut [u8] { &mut [] } + + unsafe fn slice_unchecked(&self, index: usize) -> &S { + unimplemented!() + } } /// The main ManagedVecItemPayload implementation. Uses an array in its implementation. @@ -58,6 +66,11 @@ impl ManagedVecItemPayload for ManagedVecItemPayloadBuffer { fn payload_slice_mut(&mut self) -> &mut [u8] { &mut self.buffer[..] } + + unsafe fn slice_unchecked(&self, index: usize) -> &S { + let ptr = self.buffer.as_ptr().offset(index as isize); + core::mem::transmute(ptr) + } } #[repr(transparent)] @@ -97,6 +110,10 @@ where fn payload_slice_mut(&mut self) -> &mut [u8] { self.buffer.payload_slice_mut() } + + unsafe fn slice_unchecked(&self, index: usize) -> &S { + self.buffer.slice_unchecked(index) + } } impl ManagedVecItemPayloadConcat @@ -116,25 +133,44 @@ where P0: ManagedVecItemPayloadAdd<>::Output>, { type Output = ManagedVecItemPayloadConcat>; - + fn split_from_add(payload: &Self::Output) -> (&Self, &ManagedVecItemPayloadConcat) { todo!() } +} + +pub struct ManagedVecItemPayloadEquiv +where + T: ManagedVecItem, +{ + equiv: T::PAYLOAD, +} + +impl ManagedVecItemPayload for ManagedVecItemPayloadEquiv +where + T: ManagedVecItem, +{ + fn new_buffer() -> Self { + ManagedVecItemPayloadEquiv { + equiv: ManagedVecItemPayload::new_buffer(), + } + } + fn payload_size() -> usize { + T::PAYLOAD::payload_size() + } - - // fn split_from_add( - // payload: &ManagedVecItemPayloadBuffer<$result_add>, - // ) -> ( - // &ManagedVecItemPayloadBuffer<$dec1>, - // &ManagedVecItemPayloadBuffer<$dec2>, - // ) { - // unsafe { - // let ptr1 = payload.buffer.as_ptr(); - // let ptr2 = ptr1.offset($dec1 as isize); - // (core::mem::transmute(ptr1), core::mem::transmute(ptr2)) - // } - // } + fn payload_slice(&self) -> &[u8] { + self.equiv.payload_slice() + } + + fn payload_slice_mut(&mut self) -> &mut [u8] { + self.equiv.payload_slice_mut() + } + + unsafe fn slice_unchecked(&self, index: usize) -> &S { + self.equiv.slice_unchecked(index) + } } /// Describes concatantion of smaller payloads into a larger one. @@ -151,8 +187,9 @@ where fn split_from_add(payload: &Self::Output) -> (&Self, &Rhs); } -impl ManagedVecItemPayloadAdd - for ManagedVecItemPayloadBuffer +impl

ManagedVecItemPayloadAdd for P +where + P: ManagedVecItemPayload, { type Output = Self; diff --git a/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs b/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs index 20942e70d4..470bd16053 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs @@ -1,6 +1,6 @@ use crate::api::ManagedTypeApi; -use super::{ManagedVec, ManagedVecItem}; +use super::{ManagedVec, ManagedVecItem, ManagedVecItemPayload}; impl<'a, M, T> IntoIterator for &'a ManagedVec where @@ -52,15 +52,15 @@ where if next_byte_start > self.byte_end { return None; } - let result = T::from_byte_reader(|dest_slice| { - let _ = self - .managed_vec - .buffer - .load_slice(self.byte_start, dest_slice); - }); + + let mut payload = T::PAYLOAD::new_buffer(); + let _ = self + .managed_vec + .buffer + .load_slice(self.byte_start, payload.payload_slice_mut()); self.byte_start = next_byte_start; - Some(result) + Some(T::read_from_payload(&payload)) } fn size_hint(&self) -> (usize, Option) { diff --git a/framework/base/src/types/managed/wrapped/mod.rs b/framework/base/src/types/managed/wrapped/mod.rs index f4db4e5212..38d721812e 100644 --- a/framework/base/src/types/managed/wrapped/mod.rs +++ b/framework/base/src/types/managed/wrapped/mod.rs @@ -46,8 +46,10 @@ pub use managed_option::ManagedOption; pub use managed_ref::ManagedRef; pub use managed_ref_mut::ManagedRefMut; pub use managed_vec::ManagedVec; -pub use managed_vec_item::ManagedVecItem; -pub use managed_vec_item_nested_tuple::{ManagedVecItemNestedTuple, ManagedVecItemNestedTupleSplit}; +pub use managed_vec_item::{managed_vec_item_read_from_payload_index, ManagedVecItem}; +pub use managed_vec_item_nested_tuple::{ + ManagedVecItemNestedTuple, ManagedVecItemNestedTupleSplit, +}; pub use managed_vec_item_payload::*; pub use managed_vec_owned_iter::ManagedVecOwnedIterator; pub use managed_vec_ref::ManagedVecRef; diff --git a/framework/derive/src/managed_vec_item_derive.rs b/framework/derive/src/managed_vec_item_derive.rs index c0525ee0d5..d5b91d2fbf 100644 --- a/framework/derive/src/managed_vec_item_derive.rs +++ b/framework/derive/src/managed_vec_item_derive.rs @@ -66,6 +66,24 @@ fn generate_from_byte_reader_snippets(fields: &syn::Fields) -> Vec Vec { + match fields { + syn::Fields::Named(fields_named) => fields_named + .named + .iter() + .map(|field| { + let field_ident = &field.ident; + quote! { + #field_ident: multiversx_sc::types::managed_vec_item_read_from_payload_index(payload, &mut index), + } + }) + .collect(), + _ => { + panic!("ManagedVecItem only supports named fields") + } + } +} + fn generate_to_byte_writer_snippets(fields: &syn::Fields) -> Vec { match fields { syn::Fields::Named(fields_named) => fields_named @@ -134,7 +152,10 @@ fn enum_derive(data_enum: &syn::DataEnum, ast: &syn::DeriveInput) -> TokenStream } fn read_from_payload(payload: &Self::PAYLOAD) -> Self { - todo!() + let discriminant = ::read_from_payload(payload); + match discriminant { + #(#reader_match_arms)* + } } unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>(reader: Reader) -> Self::Ref<'a> { @@ -160,6 +181,7 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token let skips_reserialization_snippets = generate_skips_reserialization_snippets(&data_struct.fields); let from_byte_reader_snippets = generate_from_byte_reader_snippets(&data_struct.fields); + let read_from_payload_snippets = generate_read_from_payload_snippets(&data_struct.fields); let to_byte_writer_snippets = generate_to_byte_writer_snippets(&data_struct.fields); let payload_buffer_snippet = generate_payload_buffer_snippet(); @@ -181,7 +203,13 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token } fn read_from_payload(payload: &Self::PAYLOAD) -> Self { - todo!() + let mut index = 0; + + unsafe { + #name { + #(#read_from_payload_snippets)* + } + } } unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>(reader: Reader) -> Self::Ref<'a> { From 08b47efbdea818e49277463aa89e57082b0e648d Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 01:32:31 +0200 Subject: [PATCH 03/13] ManagedVecItem payload refactor - cleanup --- .../managed/wrapped/esdt_token_payment.rs | 11 ++- .../types/managed/wrapped/managed_vec_item.rs | 93 ++----------------- .../wrapped/managed_vec_item_nested_tuple.rs | 2 +- .../wrapped/managed_vec_item_payload.rs | 58 +----------- 4 files changed, 22 insertions(+), 142 deletions(-) diff --git a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs index a92a9cbe16..83369820c2 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs @@ -13,7 +13,7 @@ use crate::{ derive::type_abi, }; -use super::{ManagedVec, ManagedVecItemPayloadBuffer}; +use super::{managed_vec_item_read_from_payload_index, ManagedVec, ManagedVecItemPayloadBuffer}; #[type_abi] #[derive(TopEncode, NestedEncode, Clone, PartialEq, Eq, Debug)] @@ -206,7 +206,14 @@ impl ManagedVecItem for EsdtTokenPayment { } fn read_from_payload(payload: &Self::PAYLOAD) -> Self { - todo!() + let mut index = 0; + unsafe { + EsdtTokenPayment { + token_identifier: managed_vec_item_read_from_payload_index(payload, &mut index), + token_nonce: managed_vec_item_read_from_payload_index(payload, &mut index), + amount: managed_vec_item_read_from_payload_index(payload, &mut index), + } + } } unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 484a106d41..19d714d7b9 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -10,10 +10,7 @@ use crate::{ }, }; -use super::{ - ManagedVecItemEmptyPayload, ManagedVecItemNestedTuple, ManagedVecItemNestedTupleSplit, - ManagedVecItemPayload, ManagedVecItemPayloadAdd, ManagedVecItemPayloadBuffer, -}; +use super::{ManagedVecItemPayload, ManagedVecItemPayloadAdd, ManagedVecItemPayloadBuffer}; /// Types that implement this trait can be items inside a `ManagedVec`. /// All these types need a payload, i.e a representation that gets stored @@ -173,13 +170,10 @@ impl ManagedVecItem for bool { impl ManagedVecItem for Option where - (u8, (T, ())): ManagedVecItemNestedTuple, ManagedVecItemPayloadBuffer<1>: ManagedVecItemPayloadAdd, T: ManagedVecItem, { - // type PAYLOAD = <(u8, (T, ())) as ManagedVecItemNestedTuple>::PAYLOAD; type PAYLOAD = as ManagedVecItemPayloadAdd>::Output; - // type PAYLOAD = EquivPayload<(u8, T)>; const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = Self; @@ -197,26 +191,15 @@ where } fn read_from_payload(payload: &Self::PAYLOAD) -> Self { - // let (p1, (p2, ())) = <(u8, (T, ()))>::split_all(payload); - - // let (p1, p2) = as ManagedVecItemPayloadAdd< - // T::PAYLOAD, - // >>::split_from_add(payload); - - // let disc = u8::read_from_payload(p1); - // if disc == 0 { - // None - // } else { - // Some(T::read_from_payload(p2)) - // } - - unsafe { - let disc = u8::read_from_payload(payload.slice_unchecked(0)); - if disc == 0 { - None - } else { - Some(T::read_from_payload(payload.slice_unchecked(1))) - } + let (p1, p2) = as ManagedVecItemPayloadAdd< + T::PAYLOAD, + >>::split_from_add(payload); + + let disc = u8::read_from_payload(p1); + if disc == 0 { + None + } else { + Some(T::read_from_payload(p2)) } } @@ -392,59 +375,3 @@ impl ManagedVecItem for EsdtLocalRole { ::into_byte_writer(self.as_u16(), writer) } } - -impl ManagedVecItem for () { - type PAYLOAD = ManagedVecItemEmptyPayload; - - const SKIPS_RESERIALIZATION: bool = true; - - type Ref<'a> = Self; - - fn from_byte_reader(reader: Reader) -> Self { - () - } - - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { - () - } - - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - _reader: Reader, - ) -> Self::Ref<'a> { - () - } - - fn into_byte_writer R>(self, writer: Writer) -> R { - todo!() - } -} - -impl ManagedVecItem for (Head, Tail) -where - Head: ManagedVecItem + 'static, - Tail: ManagedVecItem + 'static, -{ - type PAYLOAD = ManagedVecItemEmptyPayload; - - const SKIPS_RESERIALIZATION: bool = true; - - type Ref<'a> = Self; - - fn from_byte_reader(reader: Reader) -> Self { - todo!() - } - - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { - todo!() - } - - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - todo!() - } - - fn into_byte_writer R>(self, writer: Writer) -> R { - todo!() - } -} diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs index 7c64920cf3..1e8b5511a4 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs @@ -106,7 +106,7 @@ pub mod tests { #[test] fn split_all_test() { let p = ManagedVecItemPayloadBuffer::new_buffer(); - let (p1, (p2, ())) = <(u16, (u32, ()))>::split_all(&p); + let (_p1, (_p2, ())) = <(u16, (u32, ()))>::split_all(&p); } // fn split_all_t() diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs index ba2d7e1296..31210dd714 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs @@ -39,7 +39,7 @@ impl ManagedVecItemPayload for ManagedVecItemEmptyPayload { &mut [] } - unsafe fn slice_unchecked(&self, index: usize) -> &S { + unsafe fn slice_unchecked(&self, _index: usize) -> &S { unimplemented!() } } @@ -134,7 +134,7 @@ where { type Output = ManagedVecItemPayloadConcat>; - fn split_from_add(payload: &Self::Output) -> (&Self, &ManagedVecItemPayloadConcat) { + fn split_from_add(_payload: &Self::Output) -> (&Self, &ManagedVecItemPayloadConcat) { todo!() } } @@ -198,27 +198,6 @@ where } } -pub trait ManagedVecItemPayloadSplit: ManagedVecItemPayload { - type P1: ManagedVecItemPayload; - type P2: ManagedVecItemPayload; - - fn split_impl(&self) -> (&Self::P1, &Self::P2); -} - -impl ManagedVecItemPayloadBuffer { - pub fn split_me( - &self, - ) -> ( - &>::P1, - &>::P2, - ) - where - Self: ManagedVecItemPayloadSplit, - { - ManagedVecItemPayloadSplit::::split_impl(self) - } -} - /// Replaces a const generic expression. /// /// Remove once const generic expressions are stabilized in Rust. @@ -242,42 +221,9 @@ macro_rules! payload_add { } } } - - impl ManagedVecItemPayloadSplit<$dec1> for ManagedVecItemPayloadBuffer<$result_add> { - type P1 = ManagedVecItemPayloadBuffer<$dec1>; - type P2 = ManagedVecItemPayloadBuffer<$dec2>; - - fn split_impl( - &self, - ) -> ( - &ManagedVecItemPayloadBuffer<$dec1>, - &ManagedVecItemPayloadBuffer<$dec2>, - ) { - unsafe { - let ptr1 = self.buffer.as_ptr(); - let ptr2 = ptr1.offset($dec1 as isize); - (core::mem::transmute(ptr1), core::mem::transmute(ptr2)) - } - } - } }; } -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn payload_split() { - let payload = ManagedVecItemPayloadBuffer { - buffer: [1, 2, 3, 4, 5], - }; - let (p1, p2) = payload.split_me::<3>(); - assert_eq!(p1.buffer, [1, 2, 3]); - assert_eq!(p2.buffer, [4, 5]); - } -} - payload_add!(1usize, 1usize, 2usize); payload_add!(1usize, 2usize, 3usize); payload_add!(1usize, 3usize, 4usize); From 58090a1aa0a3d252408ab209ff9dd3451db20c2d Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 02:12:29 +0200 Subject: [PATCH 04/13] ManagedVecItem payload refactor - borrow_from_payload impl --- .../esdt_token_payment_multi_value.rs | 5 +++ .../managed/wrapped/esdt_token_payment.rs | 5 +++ .../types/managed/wrapped/managed_option.rs | 8 +++- .../src/types/managed/wrapped/managed_vec.rs | 19 +++++---- .../types/managed/wrapped/managed_vec_item.rs | 41 +++++++++++++++++++ .../wrapped/managed_vec_item_nested_tuple.rs | 4 +- .../managed/wrapped/managed_vec_owned_iter.rs | 13 +++--- .../managed/wrapped/managed_vec_ref_iter.rs | 34 +++++++-------- .../derive/src/managed_vec_item_derive.rs | 9 ++++ .../src/api/impl_vh/debug_handle_vh.rs | 4 ++ 10 files changed, 103 insertions(+), 39 deletions(-) diff --git a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs index 4eb6fc60d8..07cf680de0 100644 --- a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs +++ b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs @@ -52,6 +52,11 @@ impl ManagedVecItem for EsdtTokenPaymentMultiValue { EsdtTokenPayment::read_from_payload(payload).into() } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + // TODO: managed ref + Self::read_from_payload(payload) + } + #[inline] unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, diff --git a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs index 83369820c2..b0a62679b8 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs @@ -216,6 +216,11 @@ impl ManagedVecItem for EsdtTokenPayment { } } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + // TODO: managed ref + Self::read_from_payload(payload) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index ae77c6bc92..add7ae2669 100644 --- a/framework/base/src/types/managed/wrapped/managed_option.rs +++ b/framework/base/src/types/managed/wrapped/managed_option.rs @@ -209,7 +209,13 @@ where } fn read_from_payload(payload: &Self::PAYLOAD) -> Self { - Self::new_with_handle(use_raw_handle(i32::read_from_payload(payload))) + let handle = use_raw_handle(i32::read_from_payload(payload)); + Self::new_with_handle(handle) + } + + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + // TODO: managed ref + Self::read_from_payload(payload) } unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index 475bc300d3..de84d66904 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -141,15 +141,16 @@ where pub fn try_get(&self, index: usize) -> Option> { let byte_index = index * T::payload_size(); - let mut load_result = Ok(()); - let result = unsafe { - T::from_byte_reader_as_borrow(|dest_slice| { - load_result = self.buffer.load_slice(byte_index, dest_slice); - }) - }; - match load_result { - Ok(_) => Some(result), - Err(_) => None, + + let mut payload = T::PAYLOAD::new_buffer(); + if self + .buffer + .load_slice(byte_index, payload.payload_slice_mut()) + .is_ok() + { + unsafe { Some(T::borrow_from_payload(&payload)) } + } else { + None } } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 19d714d7b9..87e8bc3094 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -46,6 +46,8 @@ pub trait ManagedVecItem: 'static { fn read_from_payload(payload: &Self::PAYLOAD) -> Self; + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a>; + /// Parses given bytes as a representation of the object, either owned, or a reference. /// /// # Safety @@ -94,6 +96,10 @@ macro_rules! impl_int { $ty::from_be_bytes(payload.buffer) } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + $ty::from_be_bytes(payload.buffer) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -129,6 +135,10 @@ impl ManagedVecItem for usize { u32::read_from_payload(payload) as usize } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + Self::read_from_payload(payload) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -154,6 +164,10 @@ impl ManagedVecItem for bool { u8::read_from_payload(payload) > 0 } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + Self::read_from_payload(payload) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -203,6 +217,10 @@ where } } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + Self::read_from_payload(payload) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -239,6 +257,11 @@ macro_rules! impl_managed_type { unsafe { Self::from_handle(handle) } } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + let handle = use_raw_handle(i32::read_from_payload(payload)); + ManagedRef::wrap_handle(handle) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -279,6 +302,11 @@ where unsafe { Self::from_handle(handle) } } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + let handle = use_raw_handle(i32::read_from_payload(payload)); + ManagedRef::wrap_handle(handle) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -313,6 +341,11 @@ where unsafe { Self::from_handle(handle) } } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + let handle = use_raw_handle(i32::read_from_payload(payload)); + ManagedRef::wrap_handle(handle) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -341,6 +374,10 @@ impl ManagedVecItem for EsdtTokenType { u8::read_from_payload(payload).into() } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + Self::read_from_payload(payload) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { @@ -365,6 +402,10 @@ impl ManagedVecItem for EsdtLocalRole { u16::read_from_payload(payload).into() } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + Self::read_from_payload(payload) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs index 1e8b5511a4..11a7055a40 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs @@ -31,9 +31,7 @@ impl ManagedVecItemNestedTuple for () { impl<'a> ManagedVecItemNestedTupleSplit<'a> for () { type S = (); - fn split_all(_payload: &'a Self::PAYLOAD) -> Self::S { - () - } + fn split_all(_payload: &'a Self::PAYLOAD) -> Self::S {} } impl ManagedVecItemNestedTuple for (Head, Tail) diff --git a/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs b/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs index 470bd16053..8e0da8727c 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs @@ -88,14 +88,13 @@ where } self.byte_end -= T::payload_size(); - let result = T::from_byte_reader(|dest_slice| { - let _ = self - .managed_vec - .buffer - .load_slice(self.byte_end, dest_slice); - }); + let mut payload = T::PAYLOAD::new_buffer(); + let _ = self + .managed_vec + .buffer + .load_slice(self.byte_end, payload.payload_slice_mut()); - Some(result) + Some(T::read_from_payload(&payload)) } } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs b/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs index ad04b5eaf4..4703a1f61b 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs @@ -1,6 +1,6 @@ use crate::api::ManagedTypeApi; -use super::{ManagedVec, ManagedVecItem}; +use super::{ManagedVec, ManagedVecItem, ManagedVecItemPayload}; pub struct ManagedVecRefIterator<'a, M, T> where @@ -38,17 +38,16 @@ where if next_byte_start > self.byte_end { return None; } - let result = unsafe { - T::from_byte_reader_as_borrow(|dest_slice| { - let _ = self - .managed_vec - .buffer - .load_slice(self.byte_start, dest_slice); - }) - }; + + let mut payload = T::PAYLOAD::new_buffer(); + let _ = self + .managed_vec + .buffer + .load_slice(self.byte_start, payload.payload_slice_mut()); self.byte_start = next_byte_start; - Some(result) + + unsafe { Some(T::borrow_from_payload(&payload)) } } fn size_hint(&self) -> (usize, Option) { @@ -75,16 +74,13 @@ where } self.byte_end -= T::payload_size(); - let result = unsafe { - T::from_byte_reader_as_borrow(|dest_slice| { - let _ = self - .managed_vec - .buffer - .load_slice(self.byte_end, dest_slice); - }) - }; + let mut payload = T::PAYLOAD::new_buffer(); + let _ = self + .managed_vec + .buffer + .load_slice(self.byte_end, payload.payload_slice_mut()); - Some(result) + unsafe { Some(T::borrow_from_payload(&payload)) } } } diff --git a/framework/derive/src/managed_vec_item_derive.rs b/framework/derive/src/managed_vec_item_derive.rs index d5b91d2fbf..1b1d41fe69 100644 --- a/framework/derive/src/managed_vec_item_derive.rs +++ b/framework/derive/src/managed_vec_item_derive.rs @@ -158,6 +158,10 @@ fn enum_derive(data_enum: &syn::DataEnum, ast: &syn::DeriveInput) -> TokenStream } } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + Self::read_from_payload(payload) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>(reader: Reader) -> Self::Ref<'a> { Self::from_byte_reader(reader) } @@ -212,6 +216,11 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token } } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + // TODO: managed ref + Self::read_from_payload(payload) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>(reader: Reader) -> Self::Ref<'a> { Self::from_byte_reader(reader) } diff --git a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs index c60df36991..4a6d38b212 100644 --- a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs +++ b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs @@ -91,6 +91,10 @@ impl ManagedVecItem for DebugHandle { use_raw_handle(RawHandle::read_from_payload(payload)) } + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + Self::read_from_payload(payload) + } + unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( reader: Reader, ) -> Self::Ref<'a> { From b6c31f1a49400cb9475dcd67879f0f8480052f92 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 02:12:55 +0200 Subject: [PATCH 05/13] clippy fix --- .../src/types/managed/wrapped/managed_vec_item.rs | 5 +++++ .../types/managed/wrapped/managed_vec_item_payload.rs | 11 +++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 87e8bc3094..512e2d847d 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -46,6 +46,11 @@ pub trait ManagedVecItem: 'static { fn read_from_payload(payload: &Self::PAYLOAD) -> Self; + /// Parses given bytes as a representation of the object, either owned, or a reference. + /// + /// # Safety + /// + /// In certain cases this involves practically disregarding the lifetimes, hence it is unsafe. unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a>; /// Parses given bytes as a representation of the object, either owned, or a reference. diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs index 31210dd714..4d336632cf 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs @@ -68,8 +68,8 @@ impl ManagedVecItemPayload for ManagedVecItemPayloadBuffer { } unsafe fn slice_unchecked(&self, index: usize) -> &S { - let ptr = self.buffer.as_ptr().offset(index as isize); - core::mem::transmute(ptr) + let ptr = self.buffer.as_ptr().add(index); + &*ptr.cast::() } } @@ -216,8 +216,11 @@ macro_rules! payload_add { ) { unsafe { let ptr1 = payload.buffer.as_ptr(); - let ptr2 = ptr1.offset($dec1 as isize); - (core::mem::transmute(ptr1), core::mem::transmute(ptr2)) + let ptr2 = ptr1.add($dec1); + ( + &*ptr1.cast::>(), + &*ptr2.cast::>(), + ) } } } From 50c674ce67eaf8cc739c083fdb3d0f467bec2f83 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 02:20:07 +0200 Subject: [PATCH 06/13] ManagedVecItem payload refactor - remove from_byte_reader_as_borrow --- .../esdt_token_payment_multi_value.rs | 7 -- .../managed/wrapped/esdt_token_payment.rs | 6 -- .../types/managed/wrapped/managed_option.rs | 6 +- .../types/managed/wrapped/managed_vec_item.rs | 66 ------------------- .../derive/src/managed_vec_item_derive.rs | 8 --- .../src/api/impl_vh/debug_handle_vh.rs | 6 -- 6 files changed, 1 insertion(+), 98 deletions(-) diff --git a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs index 07cf680de0..299bc8bfc2 100644 --- a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs +++ b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs @@ -57,13 +57,6 @@ impl ManagedVecItem for EsdtTokenPaymentMultiValue { Self::read_from_payload(payload) } - #[inline] - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - #[inline] fn into_byte_writer R>(self, writer: Writer) -> R { self.obj.into_byte_writer(writer) diff --git a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs index b0a62679b8..80d4cc0858 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs @@ -221,12 +221,6 @@ impl ManagedVecItem for EsdtTokenPayment { Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - fn into_byte_writer R>(self, mut writer: Writer) -> R { let mut arr: [u8; 16] = [0u8; 16]; let mut index = 0; diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index add7ae2669..03af276bc9 100644 --- a/framework/base/src/types/managed/wrapped/managed_option.rs +++ b/framework/base/src/types/managed/wrapped/managed_option.rs @@ -218,11 +218,7 @@ where Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } + fn into_byte_writer R>(self, writer: Writer) -> R { ::into_byte_writer(self.handle, writer) diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 512e2d847d..c9b59721f2 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -53,15 +53,6 @@ pub trait ManagedVecItem: 'static { /// In certain cases this involves practically disregarding the lifetimes, hence it is unsafe. unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a>; - /// Parses given bytes as a representation of the object, either owned, or a reference. - /// - /// # Safety - /// - /// In certain cases this involves practically disregarding the lifetimes, hence it is unsafe. - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a>; - /// Converts the object into bytes. /// /// The output is processed by the `writer` lambda. @@ -105,12 +96,6 @@ macro_rules! impl_int { $ty::from_be_bytes(payload.buffer) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - fn into_byte_writer R>(self, mut writer: Writer) -> R { let bytes = self.to_be_bytes(); writer(&bytes) @@ -144,12 +129,6 @@ impl ManagedVecItem for usize { Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - fn into_byte_writer R>(self, mut writer: Writer) -> R { let bytes = (self as u32).to_be_bytes(); writer(&bytes) @@ -173,12 +152,6 @@ impl ManagedVecItem for bool { Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - fn into_byte_writer R>(self, writer: Writer) -> R { // true -> 1u8 // false -> 0u8 @@ -226,12 +199,6 @@ where Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - fn into_byte_writer R>(self, mut writer: Writer) -> R { let mut payload = Self::PAYLOAD::new_buffer(); let slice = payload.payload_slice_mut(); @@ -267,13 +234,6 @@ macro_rules! impl_managed_type { ManagedRef::wrap_handle(handle) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - let handle = <$ty as ManagedType>::OwnHandle::from_byte_reader(reader); - ManagedRef::wrap_handle(handle) - } - fn into_byte_writer R>(self, writer: Writer) -> R { let handle = unsafe { self.forget_into_handle() }; <$ty as ManagedType>::OwnHandle::into_byte_writer(handle, writer) @@ -312,13 +272,6 @@ where ManagedRef::wrap_handle(handle) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - let handle = >::OwnHandle::from_byte_reader(reader); - ManagedRef::wrap_handle(handle) - } - fn into_byte_writer R>(self, writer: Writer) -> R { <>::OwnHandle as ManagedVecItem>::into_byte_writer( self.get_handle(), @@ -351,13 +304,6 @@ where ManagedRef::wrap_handle(handle) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - let handle = M::ManagedBufferHandle::from_byte_reader(reader); - ManagedRef::wrap_handle(handle) - } - fn into_byte_writer R>(self, writer: Writer) -> R { let handle = unsafe { self.forget_into_handle() }; ::into_byte_writer(handle, writer) @@ -383,12 +329,6 @@ impl ManagedVecItem for EsdtTokenType { Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - fn into_byte_writer R>(self, mut writer: Writer) -> R { writer(&[self.as_u8()]) } @@ -411,12 +351,6 @@ impl ManagedVecItem for EsdtLocalRole { Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - fn into_byte_writer R>(self, writer: Writer) -> R { ::into_byte_writer(self.as_u16(), writer) } diff --git a/framework/derive/src/managed_vec_item_derive.rs b/framework/derive/src/managed_vec_item_derive.rs index 1b1d41fe69..c45d5550c2 100644 --- a/framework/derive/src/managed_vec_item_derive.rs +++ b/framework/derive/src/managed_vec_item_derive.rs @@ -162,10 +162,6 @@ fn enum_derive(data_enum: &syn::DataEnum, ast: &syn::DeriveInput) -> TokenStream Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>(reader: Reader) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - fn into_byte_writer R>(self, mut writer: Writer) -> R { let mut arr: [u8; 1] = [0u8; 1]; arr[0] = match self { @@ -221,10 +217,6 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>(reader: Reader) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - fn into_byte_writer R>(self, mut writer: Writer) -> R { #payload_buffer_snippet let mut index = 0; diff --git a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs index 4a6d38b212..8193c36331 100644 --- a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs +++ b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs @@ -95,12 +95,6 @@ impl ManagedVecItem for DebugHandle { Self::read_from_payload(payload) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - use_raw_handle(RawHandle::from_byte_reader(reader)) - } - fn into_byte_writer R>(self, writer: Writer) -> R { RawHandle::into_byte_writer(self.get_raw_handle(), writer) } From 348f046823ecf035390cf488249d9ace87f150a4 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 02:39:41 +0200 Subject: [PATCH 07/13] ManagedVecItem payload refactor - remove read_from_payload --- .../esdt_token_payment_multi_value.rs | 4 -- .../wrapped/encoded_managed_vec_item.rs | 6 +- .../managed/wrapped/esdt_token_payment.rs | 27 --------- .../types/managed/wrapped/managed_option.rs | 7 --- .../src/types/managed/wrapped/managed_vec.rs | 16 ++++-- .../types/managed/wrapped/managed_vec_item.rs | 56 ------------------- .../wrapped/managed_vec_item_payload.rs | 6 ++ .../derive/src/managed_vec_item_derive.rs | 42 -------------- .../src/api/impl_vh/debug_handle_vh.rs | 4 -- .../derive_managed_vec_item_biguint_test.rs | 10 +--- ...anaged_vec_item_esdt_token_payment_test.rs | 10 +--- .../derive_managed_vec_item_simple_enum.rs | 5 +- .../derive_managed_vec_item_struct_1_test.rs | 6 +- .../derive_managed_vec_item_struct_2_test.rs | 6 +- 14 files changed, 26 insertions(+), 179 deletions(-) diff --git a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs index 299bc8bfc2..7479df9381 100644 --- a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs +++ b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs @@ -44,10 +44,6 @@ impl ManagedVecItem for EsdtTokenPaymentMultiValue { const SKIPS_RESERIALIZATION: bool = EsdtTokenPayment::::SKIPS_RESERIALIZATION; type Ref<'a> = Self; - fn from_byte_reader(reader: Reader) -> Self { - EsdtTokenPayment::from_byte_reader(reader).into() - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { EsdtTokenPayment::read_from_payload(payload).into() } diff --git a/framework/base/src/types/managed/wrapped/encoded_managed_vec_item.rs b/framework/base/src/types/managed/wrapped/encoded_managed_vec_item.rs index fd7af7c51f..205a219a2c 100644 --- a/framework/base/src/types/managed/wrapped/encoded_managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/encoded_managed_vec_item.rs @@ -1,4 +1,4 @@ -use super::{ManagedVecItem, ManagedVecItemPayload}; +use super::ManagedVecItem; use core::{cmp::Ordering, marker::PhantomData}; pub struct EncodedManagedVecItem @@ -14,9 +14,7 @@ where T: ManagedVecItem, { pub(crate) fn decode(&self) -> T { - T::from_byte_reader(|item_bytes| { - item_bytes.copy_from_slice(self.encoded.payload_slice()); - }) + T::read_from_payload(&self.encoded) } } diff --git a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs index 80d4cc0858..836d6d642c 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs @@ -153,17 +153,6 @@ impl EsdtTokenPayment { } } -fn managed_vec_item_from_slice(arr: &[u8], index: &mut usize) -> T -where - T: ManagedVecItem, -{ - ManagedVecItem::from_byte_reader(|bytes| { - let size = T::payload_size(); - bytes.copy_from_slice(&arr[*index..*index + size]); - *index += size; - }) -} - fn managed_vec_item_to_slice(arr: &mut [u8], index: &mut usize, item: T) where T: ManagedVecItem, @@ -189,22 +178,6 @@ impl ManagedVecItem for EsdtTokenPayment { const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = Self; - fn from_byte_reader(mut reader: Reader) -> Self { - let mut arr: [u8; 16] = [0u8; 16]; - reader(&mut arr[..]); - let mut index = 0; - - let token_identifier = managed_vec_item_from_slice(&arr, &mut index); - let token_nonce = managed_vec_item_from_slice(&arr, &mut index); - let amount = managed_vec_item_from_slice(&arr, &mut index); - - EsdtTokenPayment { - token_identifier, - token_nonce, - amount, - } - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let mut index = 0; unsafe { diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index 03af276bc9..b29ab033d1 100644 --- a/framework/base/src/types/managed/wrapped/managed_option.rs +++ b/framework/base/src/types/managed/wrapped/managed_option.rs @@ -203,11 +203,6 @@ where const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = Self; - fn from_byte_reader(reader: Reader) -> Self { - let handle = T::OwnHandle::from_byte_reader(reader); - Self::new_with_handle(handle) - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let handle = use_raw_handle(i32::read_from_payload(payload)); Self::new_with_handle(handle) @@ -218,8 +213,6 @@ where Self::read_from_payload(payload) } - - fn into_byte_writer R>(self, writer: Writer) -> R { ::into_byte_writer(self.handle, writer) } diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index de84d66904..48cbaffc05 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -527,13 +527,17 @@ where return false; } let mut byte_index = 0; + let mut self_payload = T::PAYLOAD::new_buffer(); + let mut other_payload = T::PAYLOAD::new_buffer(); while byte_index < self_len { - let self_item = T::from_byte_reader(|dest_slice| { - let _ = self.buffer.load_slice(byte_index, dest_slice); - }); - let other_item = T::from_byte_reader(|dest_slice| { - let _ = other.buffer.load_slice(byte_index, dest_slice); - }); + let _ = self + .buffer + .load_slice(byte_index, self_payload.payload_slice_mut()); + let _ = self + .buffer + .load_slice(byte_index, other_payload.payload_slice_mut()); + let self_item = T::read_from_payload(&self_payload); + let other_item = T::read_from_payload(&other_payload); if self_item != other_item { return false; } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index c9b59721f2..60ffc83f5c 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -42,8 +42,6 @@ pub trait ManagedVecItem: 'static { } /// Parses given bytes as a an owned object. - fn from_byte_reader(reader: Reader) -> Self; - fn read_from_payload(payload: &Self::PAYLOAD) -> Self; /// Parses given bytes as a representation of the object, either owned, or a reference. @@ -82,12 +80,6 @@ macro_rules! impl_int { const SKIPS_RESERIALIZATION: bool = true; type Ref<'a> = Self; - fn from_byte_reader(mut reader: Reader) -> Self { - let mut arr: [u8; $payload_size] = [0u8; $payload_size]; - reader(&mut arr[..]); - $ty::from_be_bytes(arr) - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { $ty::from_be_bytes(payload.buffer) } @@ -115,12 +107,6 @@ impl ManagedVecItem for usize { const SKIPS_RESERIALIZATION: bool = true; type Ref<'a> = Self; - fn from_byte_reader(mut reader: Reader) -> Self { - let mut arr: [u8; 4] = [0u8; 4]; - reader(&mut arr[..]); - u32::from_be_bytes(arr) as usize - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { u32::read_from_payload(payload) as usize } @@ -140,10 +126,6 @@ impl ManagedVecItem for bool { const SKIPS_RESERIALIZATION: bool = true; type Ref<'a> = Self; - fn from_byte_reader(reader: Reader) -> Self { - u8::from_byte_reader(reader) > 0 - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { u8::read_from_payload(payload) > 0 } @@ -169,19 +151,6 @@ where const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = Self; - fn from_byte_reader(mut reader: Reader) -> Self { - let mut payload = Self::PAYLOAD::new_buffer(); - let payload_slice = payload.payload_slice_mut(); - reader(payload_slice); - if payload_slice[0] == 0 { - None - } else { - Some(T::from_byte_reader(|bytes| { - bytes.copy_from_slice(&payload_slice[1..]); - })) - } - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let (p1, p2) = as ManagedVecItemPayloadAdd< T::PAYLOAD, @@ -219,11 +188,6 @@ macro_rules! impl_managed_type { const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = ManagedRef<'a, M, Self>; - fn from_byte_reader(reader: Reader) -> Self { - let handle = <$ty as ManagedType>::OwnHandle::from_byte_reader(reader); - unsafe { $ty::from_handle(handle) } - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let handle = use_raw_handle(i32::read_from_payload(payload)); unsafe { Self::from_handle(handle) } @@ -257,11 +221,6 @@ where const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = ManagedRef<'a, M, Self>; - fn from_byte_reader(reader: Reader) -> Self { - let handle = >::OwnHandle::from_byte_reader(reader); - unsafe { Self::from_handle(handle) } - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let handle = use_raw_handle(i32::read_from_payload(payload)); unsafe { Self::from_handle(handle) } @@ -289,11 +248,6 @@ where const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = ManagedRef<'a, M, Self>; - fn from_byte_reader(reader: Reader) -> Self { - let handle = M::ManagedBufferHandle::from_byte_reader(reader); - unsafe { Self::from_handle(handle) } - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let handle = use_raw_handle(i32::read_from_payload(payload)); unsafe { Self::from_handle(handle) } @@ -315,12 +269,6 @@ impl ManagedVecItem for EsdtTokenType { const SKIPS_RESERIALIZATION: bool = true; type Ref<'a> = Self; - fn from_byte_reader(mut reader: Reader) -> Self { - let mut arr: [u8; 1] = [0u8; 1]; - reader(&mut arr[..]); - arr[0].into() - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { u8::read_from_payload(payload).into() } @@ -339,10 +287,6 @@ impl ManagedVecItem for EsdtLocalRole { const SKIPS_RESERIALIZATION: bool = false; // TODO: might be ok to be true, but needs testing type Ref<'a> = Self; - fn from_byte_reader(reader: Reader) -> Self { - u16::from_byte_reader(reader).into() - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { u16::read_from_payload(payload).into() } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs index 4d336632cf..9b22da64f6 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs @@ -50,6 +50,12 @@ pub struct ManagedVecItemPayloadBuffer { pub buffer: [u8; N], } +impl From<[u8; N]> for ManagedVecItemPayloadBuffer { + fn from(value: [u8; N]) -> Self { + ManagedVecItemPayloadBuffer { buffer: value } + } +} + impl ManagedVecItemPayload for ManagedVecItemPayloadBuffer { fn new_buffer() -> Self { ManagedVecItemPayloadBuffer { buffer: [0u8; N] } diff --git a/framework/derive/src/managed_vec_item_derive.rs b/framework/derive/src/managed_vec_item_derive.rs index c45d5550c2..028c833168 100644 --- a/framework/derive/src/managed_vec_item_derive.rs +++ b/framework/derive/src/managed_vec_item_derive.rs @@ -43,29 +43,6 @@ fn generate_skips_reserialization_snippets(fields: &syn::Fields) -> Vec Vec { - match fields { - syn::Fields::Named(fields_named) => fields_named - .named - .iter() - .map(|field| { - let field_ident = &field.ident; - let type_name = &field.ty; - quote! { - #field_ident: multiversx_sc::types::ManagedVecItem::from_byte_reader(|bytes| { - let next_index = index + <#type_name as multiversx_sc::types::ManagedVecItem>::payload_size(); - bytes.copy_from_slice(&payload_slice[index .. next_index]); - index = next_index; - }), - } - }) - .collect(), - _ => { - panic!("ManagedVecItem only supports named fields") - } - } -} - fn generate_read_from_payload_snippets(fields: &syn::Fields) -> Vec { match fields { syn::Fields::Named(fields_named) => fields_named @@ -143,14 +120,6 @@ fn enum_derive(data_enum: &syn::DataEnum, ast: &syn::DeriveInput) -> TokenStream const SKIPS_RESERIALIZATION: bool = true; type Ref<'a> = Self; - fn from_byte_reader(mut reader: Reader) -> Self { - let mut arr: [u8; 1] = [0u8; 1]; - reader(&mut arr[..]); - match arr[0] { - #(#reader_match_arms)* - } - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let discriminant = ::read_from_payload(payload); match discriminant { @@ -180,7 +149,6 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token let payload_nested_tuple = generate_payload_nested_tuple(&data_struct.fields); let skips_reserialization_snippets = generate_skips_reserialization_snippets(&data_struct.fields); - let from_byte_reader_snippets = generate_from_byte_reader_snippets(&data_struct.fields); let read_from_payload_snippets = generate_read_from_payload_snippets(&data_struct.fields); let to_byte_writer_snippets = generate_to_byte_writer_snippets(&data_struct.fields); @@ -192,16 +160,6 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token const SKIPS_RESERIALIZATION: bool = #(#skips_reserialization_snippets)&&*; type Ref<'a> = Self; - fn from_byte_reader(mut reader: Reader) -> Self { - #payload_buffer_snippet - reader(payload_slice); - let mut index = 0; - - #name { - #(#from_byte_reader_snippets)* - } - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let mut index = 0; diff --git a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs index 8193c36331..3a21758e6a 100644 --- a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs +++ b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs @@ -83,10 +83,6 @@ impl ManagedVecItem for DebugHandle { type Ref<'a> = Self; - fn from_byte_reader(reader: Reader) -> Self { - use_raw_handle(RawHandle::from_byte_reader(reader)) - } - fn read_from_payload(payload: &Self::PAYLOAD) -> Self { use_raw_handle(RawHandle::read_from_payload(payload)) } diff --git a/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs b/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs index 6efd920acc..9cbf9ec1b9 100644 --- a/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs @@ -65,14 +65,8 @@ fn managed_struct_from_bytes_reader() { let arr: [u8; 8] = [0xff, 0xff, 0xff, handle_bytes[3], 0x00, 0x01, 0x23, 0x45]; let struct_from_bytes = - as multiversx_sc::types::ManagedVecItem>::from_byte_reader( - |bytes| { - bytes.copy_from_slice( - &arr - [0 - .. as multiversx_sc::types::ManagedVecItem>::payload_size()], - ); - }, + as multiversx_sc::types::ManagedVecItem>::read_from_payload( + &arr.into() ); assert_eq!(s, struct_from_bytes); } diff --git a/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs b/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs index 1018747da3..84dfd54e32 100644 --- a/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs @@ -93,14 +93,8 @@ fn struct_from_bytes_reader() { ]; let struct_from_bytes = - as multiversx_sc::types::ManagedVecItem>::from_byte_reader( - |bytes| { - bytes.copy_from_slice( - &arr - [0 - .. as multiversx_sc::types::ManagedVecItem>::payload_size()], - ); - }, + as multiversx_sc::types::ManagedVecItem>::read_from_payload( + &arr.into() ); assert_eq!(s, struct_from_bytes); diff --git a/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs b/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs index 46dcceed33..11719b6872 100644 --- a/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs +++ b/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs @@ -39,9 +39,6 @@ fn enum_to_bytes_writer() { #[test] fn enum_from_bytes_reader() { let enum_from_bytes = - ::from_byte_reader(|bytes| { - assert_eq!(bytes.len(), 1); - bytes[0] = 1; - }); + ::read_from_payload(&[1u8].into()); assert_eq!(enum_from_bytes, SimpleEnum::Variant2); } diff --git a/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs b/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs index e55e6d9140..49b43b8711 100644 --- a/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs @@ -94,10 +94,6 @@ fn struct_1_from_bytes_reader() { ]; let struct_from_bytes = - ::from_byte_reader(|bytes| { - bytes.copy_from_slice( - &arr[0..::payload_size()], - ); - }); + ::read_from_payload(&arr.into()); assert_eq!(s, struct_from_bytes); } diff --git a/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs b/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs index 50bea73aac..f188f1f64d 100644 --- a/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs @@ -67,7 +67,7 @@ fn struct_2_from_bytes_reader() { }; #[rustfmt::skip] - let payload = &[ + let payload = [ /* u_8 */ 0x01, /* u_16 */ 0x00, 0x02, /* u_32 */ 0x00, 0x00, 0x00, 0x03, @@ -78,8 +78,6 @@ fn struct_2_from_bytes_reader() { ]; let struct_from_bytes = - ::from_byte_reader(|bytes| { - bytes.copy_from_slice(&payload[..]); - }); + ::read_from_payload(&payload.into()); assert_eq!(expected_struct, struct_from_bytes); } From 1db9f8e15963ea864e3fb35eb02d32222d00a947 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 02:42:39 +0200 Subject: [PATCH 08/13] clippy fix --- framework/base/src/types/managed/wrapped/managed_vec_item.rs | 5 +++++ .../src/types/managed/wrapped/managed_vec_item_payload.rs | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 60ffc83f5c..a920cafadb 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -63,6 +63,11 @@ pub trait ManagedVecItem: 'static { fn into_byte_writer R>(self, writer: Writer) -> R; } +/// Used by the ManagedVecItem derive. +/// +/// ## Safety +/// +/// Only works correctly if the given index is correct, otherwise undefined behavior is possible. pub unsafe fn managed_vec_item_read_from_payload_index(payload: &P, index: &mut usize) -> T where T: ManagedVecItem, diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs index 9b22da64f6..f8ba1b17cc 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs @@ -14,6 +14,11 @@ pub trait ManagedVecItemPayload { fn payload_slice_mut(&mut self) -> &mut [u8]; + /// Takes a sub-payload item. + /// + /// ## Safety + /// + /// Only works correctly if the given index is correct, otherwise undefined behavior is possible. unsafe fn slice_unchecked(&self, index: usize) -> &S; } From 91011d075534db269ffedfd72bfa3fe43507f27f Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 03:42:01 +0200 Subject: [PATCH 09/13] ManagedVecItem payload refactor - eq fix --- framework/base/src/types/managed/wrapped/managed_vec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index 48cbaffc05..36d965f55b 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -533,7 +533,7 @@ where let _ = self .buffer .load_slice(byte_index, self_payload.payload_slice_mut()); - let _ = self + let _ = other .buffer .load_slice(byte_index, other_payload.payload_slice_mut()); let self_item = T::read_from_payload(&self_payload); From a886acceb3271302483d1036ad69b083eee81fe9 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 03:56:50 +0200 Subject: [PATCH 10/13] ManagedVecItem payload refactor - save_to_payload impl --- .../esdt_token_payment_multi_value.rs | 4 ++ .../managed/wrapped/esdt_token_payment.rs | 15 ++++- .../types/managed/wrapped/managed_option.rs | 5 ++ .../src/types/managed/wrapped/managed_vec.rs | 4 +- .../types/managed/wrapped/managed_vec_item.rs | 67 ++++++++++++++++++- .../wrapped/managed_vec_item_payload.rs | 54 +++++++++++++++ .../base/src/types/managed/wrapped/mod.rs | 5 +- .../derive/src/managed_vec_item_derive.rs | 33 +++++++++ .../src/api/impl_vh/debug_handle_vh.rs | 4 ++ .../derive_managed_vec_item_biguint_test.rs | 19 +++--- ...anaged_vec_item_esdt_token_payment_test.rs | 19 +++--- .../derive_managed_vec_item_simple_enum.rs | 17 +++-- .../derive_managed_vec_item_struct_1_test.rs | 20 +++--- .../derive_managed_vec_item_struct_2_test.rs | 8 ++- 14 files changed, 225 insertions(+), 49 deletions(-) diff --git a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs index 7479df9381..1fd9c5ef2b 100644 --- a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs +++ b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs @@ -57,6 +57,10 @@ impl ManagedVecItem for EsdtTokenPaymentMultiValue { fn into_byte_writer R>(self, writer: Writer) -> R { self.obj.into_byte_writer(writer) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + self.obj.save_to_payload(payload); + } } impl TopEncodeMulti for EsdtTokenPaymentMultiValue diff --git a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs index 836d6d642c..435a6e223e 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs @@ -13,7 +13,10 @@ use crate::{ derive::type_abi, }; -use super::{managed_vec_item_read_from_payload_index, ManagedVec, ManagedVecItemPayloadBuffer}; +use super::{ + managed_vec_item_read_from_payload_index, managed_vec_item_save_to_payload_index, ManagedVec, + ManagedVecItemPayloadBuffer, +}; #[type_abi] #[derive(TopEncode, NestedEncode, Clone, PartialEq, Eq, Debug)] @@ -204,6 +207,16 @@ impl ManagedVecItem for EsdtTokenPayment { writer(&arr[..]) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + let mut index = 0; + + unsafe { + managed_vec_item_save_to_payload_index(self.token_identifier, payload, &mut index); + managed_vec_item_save_to_payload_index(self.token_nonce, payload, &mut index); + managed_vec_item_save_to_payload_index(self.amount, payload, &mut index); + } + } } /// The version of `EsdtTokenPayment` that contains referrences instead of owned fields. diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index b29ab033d1..9616696469 100644 --- a/framework/base/src/types/managed/wrapped/managed_option.rs +++ b/framework/base/src/types/managed/wrapped/managed_option.rs @@ -2,6 +2,7 @@ use core::marker::PhantomData; use crate::{ abi::TypeAbiFrom, + api::HandleConstraints, codec::{ DecodeErrorHandler, EncodeErrorHandler, NestedDecode, NestedDecodeInput, NestedEncode, NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, @@ -216,6 +217,10 @@ where fn into_byte_writer R>(self, writer: Writer) -> R { ::into_byte_writer(self.handle, writer) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + self.handle.get_raw_handle().save_to_payload(payload); + } } impl TopEncode for ManagedOption diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index 36d965f55b..762f2757f6 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -527,12 +527,12 @@ where return false; } let mut byte_index = 0; - let mut self_payload = T::PAYLOAD::new_buffer(); - let mut other_payload = T::PAYLOAD::new_buffer(); while byte_index < self_len { + let mut self_payload = T::PAYLOAD::new_buffer(); let _ = self .buffer .load_slice(byte_index, self_payload.payload_slice_mut()); + let mut other_payload = T::PAYLOAD::new_buffer(); let _ = other .buffer .load_slice(byte_index, other_payload.payload_slice_mut()); diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index a920cafadb..bd4b311ca2 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -3,7 +3,7 @@ use core::borrow::Borrow; use multiversx_chain_core::types::{EsdtLocalRole, EsdtTokenType}; use crate::{ - api::{use_raw_handle, ManagedTypeApi}, + api::{use_raw_handle, HandleConstraints, ManagedTypeApi}, types::{ BigInt, BigUint, EllipticCurve, ManagedAddress, ManagedBuffer, ManagedByteArray, ManagedRef, ManagedType, ManagedVec, TokenIdentifier, @@ -61,6 +61,8 @@ pub trait ManagedVecItem: 'static { /// /// Note that a destructor should not be called at this moment, since the ManagedVec will take ownership of the item. fn into_byte_writer R>(self, writer: Writer) -> R; + + fn save_to_payload(self, payload: &mut Self::PAYLOAD); } /// Used by the ManagedVecItem derive. @@ -78,6 +80,23 @@ where value } +/// Used by the ManagedVecItem derive. +/// +/// ## Safety +/// +/// Only works correctly if the given index is correct, otherwise undefined behavior is possible. +pub unsafe fn managed_vec_item_save_to_payload_index( + item: T, + payload: &mut P, + index: &mut usize, +) where + T: ManagedVecItem, + P: ManagedVecItemPayload, +{ + item.save_to_payload(payload.slice_unchecked_mut(*index)); + *index += T::PAYLOAD::payload_size(); +} + macro_rules! impl_int { ($ty:ident, $payload_size:expr) => { impl ManagedVecItem for $ty { @@ -97,6 +116,10 @@ macro_rules! impl_int { let bytes = self.to_be_bytes(); writer(&bytes) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + payload.buffer = self.to_be_bytes(); + } } }; } @@ -124,6 +147,10 @@ impl ManagedVecItem for usize { let bytes = (self as u32).to_be_bytes(); writer(&bytes) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + (self as u32).save_to_payload(payload); + } } impl ManagedVecItem for bool { @@ -145,6 +172,10 @@ impl ManagedVecItem for bool { let u8_value = u8::from(self); ::into_byte_writer(u8_value, writer) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + u8::from(self).save_to_payload(payload); + } } impl ManagedVecItem for Option @@ -184,6 +215,17 @@ where } writer(slice) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + let (p1, p2) = as ManagedVecItemPayloadAdd< + T::PAYLOAD, + >>::split_mut_from_add(payload); + + if let Some(t) = self { + 1u8.save_to_payload(p1); + t.save_to_payload(p2); + } + } } macro_rules! impl_managed_type { @@ -207,6 +249,11 @@ macro_rules! impl_managed_type { let handle = unsafe { self.forget_into_handle() }; <$ty as ManagedType>::OwnHandle::into_byte_writer(handle, writer) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + let handle = unsafe { self.forget_into_handle() }; + handle.get_raw_handle().save_to_payload(payload); + } } }; } @@ -242,6 +289,11 @@ where writer, ) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + let handle = unsafe { self.forget_into_handle() }; + handle.get_raw_handle().save_to_payload(payload); + } } impl ManagedVecItem for ManagedVec @@ -267,6 +319,11 @@ where let handle = unsafe { self.forget_into_handle() }; ::into_byte_writer(handle, writer) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + let handle = unsafe { self.forget_into_handle() }; + handle.get_raw_handle().save_to_payload(payload); + } } impl ManagedVecItem for EsdtTokenType { @@ -285,6 +342,10 @@ impl ManagedVecItem for EsdtTokenType { fn into_byte_writer R>(self, mut writer: Writer) -> R { writer(&[self.as_u8()]) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + self.as_u8().save_to_payload(payload); + } } impl ManagedVecItem for EsdtLocalRole { @@ -303,4 +364,8 @@ impl ManagedVecItem for EsdtLocalRole { fn into_byte_writer R>(self, writer: Writer) -> R { ::into_byte_writer(self.as_u16(), writer) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + self.as_u16().save_to_payload(payload); + } } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs index f8ba1b17cc..e13d878a94 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs @@ -20,6 +20,13 @@ pub trait ManagedVecItemPayload { /// /// Only works correctly if the given index is correct, otherwise undefined behavior is possible. unsafe fn slice_unchecked(&self, index: usize) -> &S; + + /// Takes a sub-payload item. + /// + /// ## Safety + /// + /// Only works correctly if the given index is correct, otherwise undefined behavior is possible. + unsafe fn slice_unchecked_mut(&mut self, index: usize) -> &mut S; } /// Empty ManagedVecItem. @@ -47,6 +54,10 @@ impl ManagedVecItemPayload for ManagedVecItemEmptyPayload { unsafe fn slice_unchecked(&self, _index: usize) -> &S { unimplemented!() } + + unsafe fn slice_unchecked_mut(&mut self, _index: usize) -> &mut S { + unimplemented!() + } } /// The main ManagedVecItemPayload implementation. Uses an array in its implementation. @@ -82,6 +93,11 @@ impl ManagedVecItemPayload for ManagedVecItemPayloadBuffer { let ptr = self.buffer.as_ptr().add(index); &*ptr.cast::() } + + unsafe fn slice_unchecked_mut(&mut self, index: usize) -> &mut S { + let ptr = self.buffer.as_mut_ptr().add(index); + &mut *ptr.cast::() + } } #[repr(transparent)] @@ -125,6 +141,10 @@ where unsafe fn slice_unchecked(&self, index: usize) -> &S { self.buffer.slice_unchecked(index) } + + unsafe fn slice_unchecked_mut(&mut self, index: usize) -> &mut S { + self.buffer.slice_unchecked_mut(index) + } } impl ManagedVecItemPayloadConcat @@ -148,6 +168,12 @@ where fn split_from_add(_payload: &Self::Output) -> (&Self, &ManagedVecItemPayloadConcat) { todo!() } + + fn split_mut_from_add( + _payload: &mut Self::Output, + ) -> (&mut Self, &mut ManagedVecItemPayloadConcat) { + todo!() + } } pub struct ManagedVecItemPayloadEquiv @@ -182,6 +208,10 @@ where unsafe fn slice_unchecked(&self, index: usize) -> &S { self.equiv.slice_unchecked(index) } + + unsafe fn slice_unchecked_mut(&mut self, index: usize) -> &mut S { + self.equiv.slice_unchecked_mut(index) + } } /// Describes concatantion of smaller payloads into a larger one. @@ -196,6 +226,8 @@ where type Output: ManagedVecItemPayload; fn split_from_add(payload: &Self::Output) -> (&Self, &Rhs); + + fn split_mut_from_add(payload: &mut Self::Output) -> (&mut Self, &mut Rhs); } impl

ManagedVecItemPayloadAdd for P @@ -207,6 +239,12 @@ where fn split_from_add(payload: &Self::Output) -> (&Self, &ManagedVecItemEmptyPayload) { (payload, &ManagedVecItemEmptyPayload) } + + fn split_mut_from_add( + _payload: &mut Self::Output, + ) -> (&mut Self, &mut ManagedVecItemEmptyPayload) { + unimplemented!() + } } /// Replaces a const generic expression. @@ -234,6 +272,22 @@ macro_rules! payload_add { ) } } + + fn split_mut_from_add( + payload: &mut Self::Output, + ) -> ( + &mut ManagedVecItemPayloadBuffer<$dec1>, + &mut ManagedVecItemPayloadBuffer<$dec2>, + ) { + unsafe { + let ptr1 = payload.buffer.as_mut_ptr(); + let ptr2 = ptr1.add($dec1); + ( + &mut *ptr1.cast::>(), + &mut *ptr2.cast::>(), + ) + } + } } }; } diff --git a/framework/base/src/types/managed/wrapped/mod.rs b/framework/base/src/types/managed/wrapped/mod.rs index 38d721812e..4ca4ad6d97 100644 --- a/framework/base/src/types/managed/wrapped/mod.rs +++ b/framework/base/src/types/managed/wrapped/mod.rs @@ -46,7 +46,10 @@ pub use managed_option::ManagedOption; pub use managed_ref::ManagedRef; pub use managed_ref_mut::ManagedRefMut; pub use managed_vec::ManagedVec; -pub use managed_vec_item::{managed_vec_item_read_from_payload_index, ManagedVecItem}; +pub use managed_vec_item::{ + managed_vec_item_read_from_payload_index, managed_vec_item_save_to_payload_index, + ManagedVecItem, +}; pub use managed_vec_item_nested_tuple::{ ManagedVecItemNestedTuple, ManagedVecItemNestedTupleSplit, }; diff --git a/framework/derive/src/managed_vec_item_derive.rs b/framework/derive/src/managed_vec_item_derive.rs index 028c833168..397d83f55a 100644 --- a/framework/derive/src/managed_vec_item_derive.rs +++ b/framework/derive/src/managed_vec_item_derive.rs @@ -84,6 +84,24 @@ fn generate_to_byte_writer_snippets(fields: &syn::Fields) -> Vec Vec { + match fields { + syn::Fields::Named(fields_named) => fields_named + .named + .iter() + .map(|field| { + let field_ident = &field.ident; + quote! { + multiversx_sc::types::managed_vec_item_save_to_payload_index(self.#field_ident, payload, &mut index); + } + }) + .collect(), + _ => { + panic!("ManagedVecItem only supports named fields") + } + } +} + fn generate_payload_buffer_snippet() -> proc_macro2::TokenStream { quote! { let mut payload = ::new_buffer(); @@ -138,6 +156,13 @@ fn enum_derive(data_enum: &syn::DataEnum, ast: &syn::DeriveInput) -> TokenStream }; writer(&arr[..]) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + let discriminant = match self { + #(#writer_match_arms)* + }; + ::save_to_payload(discriminant, payload); + } } }; gen.into() @@ -151,6 +176,7 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token generate_skips_reserialization_snippets(&data_struct.fields); let read_from_payload_snippets = generate_read_from_payload_snippets(&data_struct.fields); let to_byte_writer_snippets = generate_to_byte_writer_snippets(&data_struct.fields); + let save_to_payload_snippets = generate_save_to_payload_snippets(&data_struct.fields); let payload_buffer_snippet = generate_payload_buffer_snippet(); @@ -183,6 +209,13 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token writer(&payload_slice[..]) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + let mut index = 0; + unsafe { + #(#save_to_payload_snippets)* + } + } } }; gen.into() diff --git a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs index 3a21758e6a..2157ab2877 100644 --- a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs +++ b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs @@ -94,6 +94,10 @@ impl ManagedVecItem for DebugHandle { fn into_byte_writer R>(self, writer: Writer) -> R { RawHandle::into_byte_writer(self.get_raw_handle(), writer) } + + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + self.get_raw_handle().save_to_payload(payload); + } } impl TryStaticCast for DebugHandle {} diff --git a/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs b/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs index 9cbf9ec1b9..7f0d06be8f 100644 --- a/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs @@ -1,7 +1,9 @@ use multiversx_sc::{ api::ManagedTypeApi, - codec, - codec::derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, + codec::{ + self, + derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, + }, derive::ManagedVecItem, types::{BigUint, ManagedType, ManagedVecItemPayload}, }; @@ -39,20 +41,15 @@ fn managed_struct_to_bytes_writer() { num: 0x12345, }; - let mut payload = as multiversx_sc::types::ManagedVecItem>::PAYLOAD::new_buffer(); - let payload_slice = payload.payload_slice_mut(); - let handle_bytes = s.big_uint.get_handle().to_be_bytes(); let expected = [0xff, 0xff, 0xff, handle_bytes[3], 0x00, 0x01, 0x23, 0x45]; - as multiversx_sc::types::ManagedVecItem>::into_byte_writer( + let mut payload = as multiversx_sc::types::ManagedVecItem>::PAYLOAD::new_buffer(); + as multiversx_sc::types::ManagedVecItem>::save_to_payload( s, - |bytes| { - payload_slice.copy_from_slice(bytes); - - assert_eq!(payload_slice, expected); - }, + &mut payload, ); + assert_eq!(payload.buffer, expected); } #[test] diff --git a/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs b/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs index 84dfd54e32..c6dea79b94 100644 --- a/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs @@ -1,7 +1,9 @@ use multiversx_sc::{ api::ManagedTypeApi, - codec, - codec::derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, + codec::{ + self, + derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, + }, derive::ManagedVecItem, types::{ BigUint, EsdtTokenPayment, ManagedByteArray, ManagedType, ManagedVecItemPayload, @@ -50,9 +52,6 @@ fn struct_to_bytes_writer() { eth_address_2: ManagedByteArray::new_from_bytes(&[2u8; 20]), }; - let mut payload = as multiversx_sc::types::ManagedVecItem>::PAYLOAD::new_buffer(); - let payload_slice = payload.payload_slice_mut(); - let handle1 = s.token.token_identifier.get_handle().to_be_bytes(); let handle2 = s.token.amount.get_handle().to_be_bytes(); let handle3 = s.eth_address_1.get_handle().to_be_bytes(); @@ -63,14 +62,12 @@ fn struct_to_bytes_writer() { handle3[1], handle3[2], handle3[3], handle4[0], handle4[1], handle4[2], handle4[3], ]; - as multiversx_sc::types::ManagedVecItem>::into_byte_writer( + let mut payload = as multiversx_sc::types::ManagedVecItem>::PAYLOAD::new_buffer(); + as multiversx_sc::types::ManagedVecItem>::save_to_payload( s, - |bytes| { - payload_slice.copy_from_slice(bytes); - - assert_eq!(payload_slice, expected); - }, + &mut payload, ); + assert_eq!(payload.buffer, expected); } #[test] diff --git a/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs b/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs index 11719b6872..5a41283613 100644 --- a/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs +++ b/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs @@ -1,7 +1,10 @@ use multiversx_sc::{ - codec, - codec::derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, + codec::{ + self, + derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, + }, derive::ManagedVecItem, + types::{ManagedVecItemPayload, ManagedVecItemPayloadBuffer}, }; // to test, run the following command in the crate folder: @@ -27,13 +30,13 @@ fn enum_static() { #[test] fn enum_to_bytes_writer() { - ::into_byte_writer( + let mut payload = ManagedVecItemPayloadBuffer::new_buffer(); + ::save_to_payload( SimpleEnum::Variant1, - |bytes| { - assert_eq!(bytes.len(), 1); - assert_eq!(bytes[0], 0); - }, + &mut payload, ); + + assert_eq!(payload.buffer, [0]); } #[test] diff --git a/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs b/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs index 49b43b8711..20746bcb80 100644 --- a/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs @@ -65,18 +65,14 @@ fn struct_1_to_bytes_writer() { }; let mut payload = ::PAYLOAD::new_buffer(); - let payload_slice = payload.payload_slice_mut(); - - ::into_byte_writer(s, |bytes| { - payload_slice.copy_from_slice(bytes); - assert_eq!( - payload_slice, - [ - 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x01, - ] - ); - }); + ::save_to_payload(s, &mut payload); + assert_eq!( + payload.buffer, + [ + 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x01, + ] + ); } #[test] diff --git a/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs b/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs index f188f1f64d..641bb04a0b 100644 --- a/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs @@ -1,3 +1,5 @@ +use multiversx_sc::types::{ManagedVecItemPayload, ManagedVecItemPayloadBuffer}; + multiversx_sc::derive_imports!(); // to test, run the following command in the crate folder: @@ -49,9 +51,9 @@ fn struct_to_bytes_writer() { /* arr */ 0x61, 0x11, 0x62, 0x22, ]; - ::into_byte_writer(s, |bytes| { - assert_eq!(bytes, &expected_payload[..]); - }); + let mut payload = ManagedVecItemPayloadBuffer::new_buffer(); + ::save_to_payload(s, &mut payload); + assert_eq!(payload.buffer, &expected_payload[..]); } #[test] From 01a849e9a31c8b56f88b5a7d286f8cacb748dd0c Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 10:03:20 +0200 Subject: [PATCH 11/13] ManagedVecItem payload refactor - remove into_byte_writer --- .../esdt_token_payment_multi_value.rs | 5 -- .../managed/wrapped/esdt_token_payment.rs | 22 ------- .../types/managed/wrapped/managed_option.rs | 4 -- .../src/types/managed/wrapped/managed_vec.rs | 16 ++--- .../types/managed/wrapped/managed_vec_item.rs | 60 +------------------ .../derive/src/managed_vec_item_derive.rs | 50 ---------------- .../src/api/impl_vh/debug_handle_vh.rs | 4 -- 7 files changed, 10 insertions(+), 151 deletions(-) diff --git a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs index 1fd9c5ef2b..d881b6a995 100644 --- a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs +++ b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs @@ -53,11 +53,6 @@ impl ManagedVecItem for EsdtTokenPaymentMultiValue { Self::read_from_payload(payload) } - #[inline] - fn into_byte_writer R>(self, writer: Writer) -> R { - self.obj.into_byte_writer(writer) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { self.obj.save_to_payload(payload); } diff --git a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs index 435a6e223e..b676fa42cc 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs @@ -156,17 +156,6 @@ impl EsdtTokenPayment { } } -fn managed_vec_item_to_slice(arr: &mut [u8], index: &mut usize, item: T) -where - T: ManagedVecItem, -{ - ManagedVecItem::into_byte_writer(item, |bytes| { - let size = T::payload_size(); - arr[*index..*index + size].copy_from_slice(bytes); - *index += size; - }); -} - impl IntoMultiValue for EsdtTokenPayment { type MultiValue = EsdtTokenPaymentMultiValue; @@ -197,17 +186,6 @@ impl ManagedVecItem for EsdtTokenPayment { Self::read_from_payload(payload) } - fn into_byte_writer R>(self, mut writer: Writer) -> R { - let mut arr: [u8; 16] = [0u8; 16]; - let mut index = 0; - - managed_vec_item_to_slice(&mut arr, &mut index, self.token_identifier); - managed_vec_item_to_slice(&mut arr, &mut index, self.token_nonce); - managed_vec_item_to_slice(&mut arr, &mut index, self.amount); - - writer(&arr[..]) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { let mut index = 0; diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index 9616696469..c7ee9371b9 100644 --- a/framework/base/src/types/managed/wrapped/managed_option.rs +++ b/framework/base/src/types/managed/wrapped/managed_option.rs @@ -214,10 +214,6 @@ where Self::read_from_payload(payload) } - fn into_byte_writer R>(self, writer: Writer) -> R { - ::into_byte_writer(self.handle, writer) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { self.handle.get_raw_handle().save_to_payload(payload); } diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index 762f2757f6..4bbf073088 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -201,7 +201,9 @@ where pub fn set(&mut self, index: usize, item: T) -> Result<(), InvalidSliceError> { let byte_index = index * T::payload_size(); - item.into_byte_writer(|slice| self.buffer.set_slice(byte_index, slice)) + let mut payload = T::PAYLOAD::new_buffer(); + item.save_to_payload(&mut payload); + self.buffer.set_slice(byte_index, payload.payload_slice()) } /// Returns a new `ManagedVec`, containing the [start_index, end_index) range of elements. @@ -214,9 +216,9 @@ where } pub fn push(&mut self, item: T) { - item.into_byte_writer(|bytes| { - self.buffer.append_bytes(bytes); - }); + let mut payload = T::PAYLOAD::new_buffer(); + item.save_to_payload(&mut payload); + self.buffer.append_bytes(payload.payload_slice()); } pub fn remove(&mut self, index: usize) { @@ -260,9 +262,9 @@ where } pub fn overwrite_with_single_item(&mut self, item: T) { - item.into_byte_writer(|bytes| { - self.buffer.overwrite(bytes); - }); + let mut payload = T::PAYLOAD::new_buffer(); + item.save_to_payload(&mut payload); + self.buffer.overwrite(payload.payload_slice()); } /// Appends all the contents of another managed vec at the end of the current one. diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index bd4b311ca2..0752796145 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -53,15 +53,9 @@ pub trait ManagedVecItem: 'static { /// Converts the object into bytes. /// - /// The output is processed by the `writer` lambda. - /// The writer is provided by the caller. - /// The callee will use it to pass on the bytes. - /// /// The method is used when instering (push, overwrite) into a ManagedVec. /// /// Note that a destructor should not be called at this moment, since the ManagedVec will take ownership of the item. - fn into_byte_writer R>(self, writer: Writer) -> R; - fn save_to_payload(self, payload: &mut Self::PAYLOAD); } @@ -112,11 +106,6 @@ macro_rules! impl_int { $ty::from_be_bytes(payload.buffer) } - fn into_byte_writer R>(self, mut writer: Writer) -> R { - let bytes = self.to_be_bytes(); - writer(&bytes) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { payload.buffer = self.to_be_bytes(); } @@ -143,11 +132,6 @@ impl ManagedVecItem for usize { Self::read_from_payload(payload) } - fn into_byte_writer R>(self, mut writer: Writer) -> R { - let bytes = (self as u32).to_be_bytes(); - writer(&bytes) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { (self as u32).save_to_payload(payload); } @@ -166,14 +150,9 @@ impl ManagedVecItem for bool { Self::read_from_payload(payload) } - fn into_byte_writer R>(self, writer: Writer) -> R { + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { // true -> 1u8 // false -> 0u8 - let u8_value = u8::from(self); - ::into_byte_writer(u8_value, writer) - } - - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { u8::from(self).save_to_payload(payload); } } @@ -204,18 +183,6 @@ where Self::read_from_payload(payload) } - fn into_byte_writer R>(self, mut writer: Writer) -> R { - let mut payload = Self::PAYLOAD::new_buffer(); - let slice = payload.payload_slice_mut(); - if let Some(t) = self { - slice[0] = 1; - T::into_byte_writer(t, |bytes| { - slice[1..].copy_from_slice(bytes); - }); - } - writer(slice) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { let (p1, p2) = as ManagedVecItemPayloadAdd< T::PAYLOAD, @@ -245,11 +212,6 @@ macro_rules! impl_managed_type { ManagedRef::wrap_handle(handle) } - fn into_byte_writer R>(self, writer: Writer) -> R { - let handle = unsafe { self.forget_into_handle() }; - <$ty as ManagedType>::OwnHandle::into_byte_writer(handle, writer) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { let handle = unsafe { self.forget_into_handle() }; handle.get_raw_handle().save_to_payload(payload); @@ -283,13 +245,6 @@ where ManagedRef::wrap_handle(handle) } - fn into_byte_writer R>(self, writer: Writer) -> R { - <>::OwnHandle as ManagedVecItem>::into_byte_writer( - self.get_handle(), - writer, - ) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { let handle = unsafe { self.forget_into_handle() }; handle.get_raw_handle().save_to_payload(payload); @@ -315,11 +270,6 @@ where ManagedRef::wrap_handle(handle) } - fn into_byte_writer R>(self, writer: Writer) -> R { - let handle = unsafe { self.forget_into_handle() }; - ::into_byte_writer(handle, writer) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { let handle = unsafe { self.forget_into_handle() }; handle.get_raw_handle().save_to_payload(payload); @@ -339,10 +289,6 @@ impl ManagedVecItem for EsdtTokenType { Self::read_from_payload(payload) } - fn into_byte_writer R>(self, mut writer: Writer) -> R { - writer(&[self.as_u8()]) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { self.as_u8().save_to_payload(payload); } @@ -361,10 +307,6 @@ impl ManagedVecItem for EsdtLocalRole { Self::read_from_payload(payload) } - fn into_byte_writer R>(self, writer: Writer) -> R { - ::into_byte_writer(self.as_u16(), writer) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { self.as_u16().save_to_payload(payload); } diff --git a/framework/derive/src/managed_vec_item_derive.rs b/framework/derive/src/managed_vec_item_derive.rs index 397d83f55a..1531b00610 100644 --- a/framework/derive/src/managed_vec_item_derive.rs +++ b/framework/derive/src/managed_vec_item_derive.rs @@ -61,29 +61,6 @@ fn generate_read_from_payload_snippets(fields: &syn::Fields) -> Vec Vec { - match fields { - syn::Fields::Named(fields_named) => fields_named - .named - .iter() - .map(|field| { - let field_ident = &field.ident; - let type_name = &field.ty; - quote! { - multiversx_sc::types::ManagedVecItem::into_byte_writer(self.#field_ident, |bytes| { - let next_index = index + <#type_name as multiversx_sc::types::ManagedVecItem>::payload_size(); - payload_slice[index .. next_index].copy_from_slice(bytes); - index = next_index; - }); - } - }) - .collect(), - _ => { - panic!("ManagedVecItem only supports named fields") - } - } -} - fn generate_save_to_payload_snippets(fields: &syn::Fields) -> Vec { match fields { syn::Fields::Named(fields_named) => fields_named @@ -102,13 +79,6 @@ fn generate_save_to_payload_snippets(fields: &syn::Fields) -> Vec proc_macro2::TokenStream { - quote! { - let mut payload = ::new_buffer(); - let payload_slice = multiversx_sc::types::ManagedVecItemPayload::payload_slice_mut(&mut payload); - } -} - fn enum_derive(data_enum: &syn::DataEnum, ast: &syn::DeriveInput) -> TokenStream { let name = &ast.ident; let (impl_generics, ty_generics, where_clause) = &ast.generics.split_for_impl(); @@ -149,14 +119,6 @@ fn enum_derive(data_enum: &syn::DataEnum, ast: &syn::DeriveInput) -> TokenStream Self::read_from_payload(payload) } - fn into_byte_writer R>(self, mut writer: Writer) -> R { - let mut arr: [u8; 1] = [0u8; 1]; - arr[0] = match self { - #(#writer_match_arms)* - }; - writer(&arr[..]) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { let discriminant = match self { #(#writer_match_arms)* @@ -175,11 +137,8 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token let skips_reserialization_snippets = generate_skips_reserialization_snippets(&data_struct.fields); let read_from_payload_snippets = generate_read_from_payload_snippets(&data_struct.fields); - let to_byte_writer_snippets = generate_to_byte_writer_snippets(&data_struct.fields); let save_to_payload_snippets = generate_save_to_payload_snippets(&data_struct.fields); - let payload_buffer_snippet = generate_payload_buffer_snippet(); - let gen = quote! { impl #impl_generics multiversx_sc::types::ManagedVecItem for #name #ty_generics #where_clause { type PAYLOAD = <#payload_nested_tuple as multiversx_sc::types::ManagedVecItemNestedTuple>::PAYLOAD; @@ -201,15 +160,6 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token Self::read_from_payload(payload) } - fn into_byte_writer R>(self, mut writer: Writer) -> R { - #payload_buffer_snippet - let mut index = 0; - - #(#to_byte_writer_snippets)* - - writer(&payload_slice[..]) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { let mut index = 0; unsafe { diff --git a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs index 2157ab2877..64fcd15fa9 100644 --- a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs +++ b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs @@ -91,10 +91,6 @@ impl ManagedVecItem for DebugHandle { Self::read_from_payload(payload) } - fn into_byte_writer R>(self, writer: Writer) -> R { - RawHandle::into_byte_writer(self.get_raw_handle(), writer) - } - fn save_to_payload(self, payload: &mut Self::PAYLOAD) { self.get_raw_handle().save_to_payload(payload); } From 2afe44488b6ac3338c8c050d0fdf61b4d7d20a73 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 10:26:22 +0200 Subject: [PATCH 12/13] ManagedVecItem payload refactor - cleanup --- .../wrapped/managed_vec_item_nested_tuple.rs | 79 ------------ .../wrapped/managed_vec_item_payload.rs | 118 ------------------ .../base/src/types/managed/wrapped/mod.rs | 4 +- 3 files changed, 1 insertion(+), 200 deletions(-) diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs index 11a7055a40..3a25bf4993 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs @@ -5,33 +5,11 @@ use super::{ /// Syntactic sugar, that allows us to more easily represent composite payloads as nested tuples. pub trait ManagedVecItemNestedTuple { type PAYLOAD: ManagedVecItemPayload; - type Split1: ManagedVecItemPayload; - type Split2: ManagedVecItemPayload; - - fn split_payload(payload: &Self::PAYLOAD) -> (&Self::Split1, &Self::Split2); -} - -pub trait ManagedVecItemNestedTupleSplit<'a>: ManagedVecItemNestedTuple { - type S; - - fn split_all(payload: &'a Self::PAYLOAD) -> Self::S; } /// End of the list. impl ManagedVecItemNestedTuple for () { type PAYLOAD = ManagedVecItemEmptyPayload; - type Split1 = ManagedVecItemEmptyPayload; - type Split2 = ManagedVecItemEmptyPayload; - - fn split_payload(_payload: &Self::PAYLOAD) -> (&Self::Split1, &Self::Split2) { - (&ManagedVecItemEmptyPayload, &ManagedVecItemEmptyPayload) - } -} - -impl<'a> ManagedVecItemNestedTupleSplit<'a> for () { - type S = (); - - fn split_all(_payload: &'a Self::PAYLOAD) -> Self::S {} } impl ManagedVecItemNestedTuple for (Head, Tail) @@ -41,51 +19,10 @@ where Head::PAYLOAD: ManagedVecItemPayloadAdd, { type PAYLOAD = >::Output; - type Split1 = ::PAYLOAD; - type Split2 = ::PAYLOAD; - - fn split_payload(payload: &Self::PAYLOAD) -> (&Self::Split1, &Self::Split2) { - Head::PAYLOAD::split_from_add(payload) - } } -impl<'a, Head, Tail> ManagedVecItemNestedTupleSplit<'a> for (Head, Tail) -where - Head: ManagedVecItem, - Tail: ManagedVecItemNestedTupleSplit<'a>, - Head::PAYLOAD: ManagedVecItemPayloadAdd, - Tail::PAYLOAD: 'a, -{ - type S = (&'a Head::PAYLOAD, Tail::S); - - fn split_all(payload: &'a Self::PAYLOAD) -> Self::S { - let (hp, tp) = Head::PAYLOAD::split_from_add(payload); - (hp, Tail::split_all(tp)) - } -} - -// pub fn split_payload( -// payload: &<(Head, Tail) as ManagedVecItemNestedTuple>::PAYLOAD, -// ) -> (&Head::PAYLOAD, &Tail::PAYLOAD) -// where -// Head: ManagedVecItem, -// Tail: ManagedVecItemNestedTuple, -// Head::PAYLOAD: ManagedVecItemPayloadAdd, -// // (Head, Tail): ManagedVecItemNestedTuple, -// { -// >::split_from_add(payload) -// // <(Head, Tail) as ManagedVecItemNestedTuple>::PAYLOAD as -// // unsafe { -// // let ptr1 = payload.buffer.as_ptr(); -// // let ptr2 = ptr1.offset($dec1 as isize); -// // (core::mem::transmute(ptr1), core::mem::transmute(ptr2)) -// // } -// } - #[cfg(test)] pub mod tests { - use crate::types::ManagedVecItemPayloadBuffer; - use super::*; #[test] @@ -100,20 +37,4 @@ pub mod tests { fn assert_payload_size(expected_size: usize) { assert_eq!(N::PAYLOAD::payload_size(), expected_size); } - - #[test] - fn split_all_test() { - let p = ManagedVecItemPayloadBuffer::new_buffer(); - let (_p1, (_p2, ())) = <(u16, (u32, ()))>::split_all(&p); - } - - // fn split_all_t() - // where - // T: ManagedVecItem, - // ManagedVecItemPayloadBuffer<1>: ManagedVecItemPayloadAdd, - // (u16, (T, ())): ManagedVecItemNestedTuple, - // { - // let p = ManagedVecItemPayloadBuffer::new_buffer(); - // let (p1, (p2, ())) = <(u16, (T, ()))>::split_all(&p); - // } } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs index e13d878a94..a3a9c58475 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs @@ -1,7 +1,3 @@ -use core::marker::PhantomData; - -use super::ManagedVecItem; - /// Describes the binary represetnation of a ManagedVecItem. /// /// It is always an array that can be allocated directly on stack. @@ -100,120 +96,6 @@ impl ManagedVecItemPayload for ManagedVecItemPayloadBuffer { } } -#[repr(transparent)] -pub struct ManagedVecItemPayloadConcat -where - P1: ManagedVecItemPayload, - P2: ManagedVecItemPayload, - P1: ManagedVecItemPayloadAdd, -{ - _phantom_1: PhantomData, - _phantom_2: PhantomData, - buffer: >::Output, -} - -impl ManagedVecItemPayload for ManagedVecItemPayloadConcat -where - P1: ManagedVecItemPayload, - P2: ManagedVecItemPayload, - P1: ManagedVecItemPayloadAdd, -{ - fn new_buffer() -> Self { - ManagedVecItemPayloadConcat { - _phantom_1: PhantomData, - _phantom_2: PhantomData, - buffer: ManagedVecItemPayload::new_buffer(), - } - } - - fn payload_size() -> usize { - >::Output::payload_size() - } - - fn payload_slice(&self) -> &[u8] { - self.buffer.payload_slice() - } - - fn payload_slice_mut(&mut self) -> &mut [u8] { - self.buffer.payload_slice_mut() - } - - unsafe fn slice_unchecked(&self, index: usize) -> &S { - self.buffer.slice_unchecked(index) - } - - unsafe fn slice_unchecked_mut(&mut self, index: usize) -> &mut S { - self.buffer.slice_unchecked_mut(index) - } -} - -impl ManagedVecItemPayloadConcat -where - P1: ManagedVecItemPayload, - P2: ManagedVecItemPayload, - P1: ManagedVecItemPayloadAdd, -{ -} - -impl ManagedVecItemPayloadAdd> for P0 -where - P0: ManagedVecItemPayload, - P1: ManagedVecItemPayload, - P2: ManagedVecItemPayload, - P1: ManagedVecItemPayloadAdd, - P0: ManagedVecItemPayloadAdd<>::Output>, -{ - type Output = ManagedVecItemPayloadConcat>; - - fn split_from_add(_payload: &Self::Output) -> (&Self, &ManagedVecItemPayloadConcat) { - todo!() - } - - fn split_mut_from_add( - _payload: &mut Self::Output, - ) -> (&mut Self, &mut ManagedVecItemPayloadConcat) { - todo!() - } -} - -pub struct ManagedVecItemPayloadEquiv -where - T: ManagedVecItem, -{ - equiv: T::PAYLOAD, -} - -impl ManagedVecItemPayload for ManagedVecItemPayloadEquiv -where - T: ManagedVecItem, -{ - fn new_buffer() -> Self { - ManagedVecItemPayloadEquiv { - equiv: ManagedVecItemPayload::new_buffer(), - } - } - - fn payload_size() -> usize { - T::PAYLOAD::payload_size() - } - - fn payload_slice(&self) -> &[u8] { - self.equiv.payload_slice() - } - - fn payload_slice_mut(&mut self) -> &mut [u8] { - self.equiv.payload_slice_mut() - } - - unsafe fn slice_unchecked(&self, index: usize) -> &S { - self.equiv.slice_unchecked(index) - } - - unsafe fn slice_unchecked_mut(&mut self, index: usize) -> &mut S { - self.equiv.slice_unchecked_mut(index) - } -} - /// Describes concatantion of smaller payloads into a larger one. /// /// There is no runtime implementation, just a type-level addition. diff --git a/framework/base/src/types/managed/wrapped/mod.rs b/framework/base/src/types/managed/wrapped/mod.rs index 4ca4ad6d97..5086c3bc26 100644 --- a/framework/base/src/types/managed/wrapped/mod.rs +++ b/framework/base/src/types/managed/wrapped/mod.rs @@ -50,9 +50,7 @@ pub use managed_vec_item::{ managed_vec_item_read_from_payload_index, managed_vec_item_save_to_payload_index, ManagedVecItem, }; -pub use managed_vec_item_nested_tuple::{ - ManagedVecItemNestedTuple, ManagedVecItemNestedTupleSplit, -}; +pub use managed_vec_item_nested_tuple::ManagedVecItemNestedTuple; pub use managed_vec_item_payload::*; pub use managed_vec_owned_iter::ManagedVecOwnedIterator; pub use managed_vec_ref::ManagedVecRef; From cb60d95f77f66830b9220be7a6d07e3285e23f84 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 27 Nov 2024 14:45:41 +0200 Subject: [PATCH 13/13] ManagedVecItem payload refactor - fix after merge --- .../multi_value_managed_vec_counted.rs | 14 +- .../types/managed/wrapped/managed_vec_item.rs | 127 ++++++------------ 2 files changed, 48 insertions(+), 93 deletions(-) diff --git a/framework/base/src/types/managed/multi_value/multi_value_managed_vec_counted.rs b/framework/base/src/types/managed/multi_value/multi_value_managed_vec_counted.rs index a46016e69a..0cb695e0d5 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_managed_vec_counted.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_managed_vec_counted.rs @@ -98,18 +98,16 @@ where const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = Self; - fn from_byte_reader(reader: Reader) -> Self { - Self::from(ManagedVec::::from_byte_reader(reader)) + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { + Self::from(ManagedVec::::read_from_payload(payload)) } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + Self::read_from_payload(payload) } - fn into_byte_writer R>(self, writer: Writer) -> R { - self.contents.into_byte_writer(writer) + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + self.contents.save_to_payload(payload); } } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 94a4c6cd1f..65ed262a41 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -11,7 +11,10 @@ use crate::{ }, }; -use super::{ManagedVecItemPayload, ManagedVecItemPayloadAdd, ManagedVecItemPayloadBuffer}; +use super::{ + ManagedVecItemNestedTuple, ManagedVecItemPayload, ManagedVecItemPayloadAdd, + ManagedVecItemPayloadBuffer, +}; /// Types that implement this trait can be items inside a `ManagedVec`. /// All these types need a payload, i.e a representation that gets stored @@ -323,49 +326,30 @@ where const SKIPS_RESERIALIZATION: bool = T1::SKIPS_RESERIALIZATION && T2::SKIPS_RESERIALIZATION; type Ref<'a> = Self; - fn from_byte_reader(mut reader: Reader) -> Self { - let mut payload = ::new_buffer(); - let payload_slice = ManagedVecItemPayload::payload_slice_mut(&mut payload); - reader(payload_slice); + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let mut index = 0; - - ( - T1::from_byte_reader(|bytes| { - let next_index = index + T1::payload_size(); - bytes.copy_from_slice(&payload_slice[index..next_index]); - index = next_index; - }), - T2::from_byte_reader(|bytes| { - let next_index = index + T2::payload_size(); - bytes.copy_from_slice(&payload_slice[index..next_index]); - index = next_index; - }), - ) - .into() + unsafe { + ( + managed_vec_item_read_from_payload_index(payload, &mut index), + managed_vec_item_read_from_payload_index(payload, &mut index), + ) + .into() + } } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + // TODO: tuple of refs + Self::read_from_payload(payload) } - fn into_byte_writer R>(self, mut writer: Writer) -> R { - let mut payload = Self::PAYLOAD::new_buffer(); - let payload_slice = ManagedVecItemPayload::payload_slice_mut(&mut payload); + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + let tuple = self.into_tuple(); let mut index = 0; - let (t1, t2) = self.into_tuple(); - T1::into_byte_writer(t1, |bytes| { - let next_index = index + T1::payload_size(); - payload_slice[index..next_index].copy_from_slice(bytes); - index = next_index; - }); - T2::into_byte_writer(t2, |bytes| { - let next_index = index + T2::payload_size(); - payload_slice[index..next_index].copy_from_slice(bytes); - index = next_index; - }); - writer(payload_slice) + + unsafe { + managed_vec_item_save_to_payload_index(tuple.0, payload, &mut index); + managed_vec_item_save_to_payload_index(tuple.1, payload, &mut index); + } } } @@ -380,58 +364,31 @@ where const SKIPS_RESERIALIZATION: bool = T1::SKIPS_RESERIALIZATION && T2::SKIPS_RESERIALIZATION; type Ref<'a> = Self; - fn from_byte_reader(mut reader: Reader) -> Self { - let mut payload = ::new_buffer(); - let payload_slice = ManagedVecItemPayload::payload_slice_mut(&mut payload); - reader(payload_slice); + fn read_from_payload(payload: &Self::PAYLOAD) -> Self { let mut index = 0; - - ( - T1::from_byte_reader(|bytes| { - let next_index = index + T1::payload_size(); - bytes.copy_from_slice(&payload_slice[index..next_index]); - index = next_index; - }), - T2::from_byte_reader(|bytes| { - let next_index = index + T2::payload_size(); - bytes.copy_from_slice(&payload_slice[index..next_index]); - index = next_index; - }), - T3::from_byte_reader(|bytes| { - let next_index = index + T3::payload_size(); - bytes.copy_from_slice(&payload_slice[index..next_index]); - index = next_index; - }), - ) - .into() + unsafe { + ( + managed_vec_item_read_from_payload_index(payload, &mut index), + managed_vec_item_read_from_payload_index(payload, &mut index), + managed_vec_item_read_from_payload_index(payload, &mut index), + ) + .into() + } } - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) + unsafe fn borrow_from_payload<'a>(payload: &Self::PAYLOAD) -> Self::Ref<'a> { + // TODO: tuple of refs + Self::read_from_payload(payload) } - fn into_byte_writer R>(self, mut writer: Writer) -> R { - let mut payload = Self::PAYLOAD::new_buffer(); - let payload_slice = ManagedVecItemPayload::payload_slice_mut(&mut payload); + fn save_to_payload(self, payload: &mut Self::PAYLOAD) { + let tuple = self.into_tuple(); let mut index = 0; - let (t1, t2, t3) = self.into_tuple(); - T1::into_byte_writer(t1, |bytes| { - let next_index = index + T1::payload_size(); - payload_slice[index..next_index].copy_from_slice(bytes); - index = next_index; - }); - T2::into_byte_writer(t2, |bytes| { - let next_index = index + T2::payload_size(); - payload_slice[index..next_index].copy_from_slice(bytes); - index = next_index; - }); - T3::into_byte_writer(t3, |bytes| { - let next_index = index + T2::payload_size(); - payload_slice[index..next_index].copy_from_slice(bytes); - index = next_index; - }); - writer(payload_slice) + + unsafe { + managed_vec_item_save_to_payload_index(tuple.0, payload, &mut index); + managed_vec_item_save_to_payload_index(tuple.1, payload, &mut index); + managed_vec_item_save_to_payload_index(tuple.2, payload, &mut index); + } } }