Skip to content

Commit

Permalink
Merge pull request #1899 from multiversx/refactor-ManagedResultArgLoader
Browse files Browse the repository at this point in the history
refactor: ManagedResultArgLoader replaced with ManagedVec iterators
  • Loading branch information
andrei-marinica authored Dec 12, 2024
2 parents 8df600b + 3f2771d commit bef75c5
Show file tree
Hide file tree
Showing 15 changed files with 143 additions and 144 deletions.
2 changes: 0 additions & 2 deletions framework/base/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ mod arg_nested_tuple;
mod bytes_arg_loader;
pub mod call_value_init;
mod finish;
mod managed_result_arg_loader;
mod signal_error;

pub use arg_de_input::*;
Expand All @@ -18,5 +17,4 @@ use arg_loader_single::*;
pub use arg_nested_tuple::*;
pub use bytes_arg_loader::*;
pub use finish::*;
pub use managed_result_arg_loader::*;
pub use signal_error::*;
19 changes: 8 additions & 11 deletions framework/base/src/io/arg_nested_tuple.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use unwrap_infallible::UnwrapInfallible;

use super::{EndpointDynArgLoader, EndpointSingleArgLoader, ManagedResultArgLoader};
use super::{EndpointDynArgLoader, EndpointSingleArgLoader};
use crate::{
api::{
const_handles, use_raw_handle, EndpointArgumentApi, EndpointArgumentApiImpl, ErrorApi,
ErrorApiImpl, ManagedTypeApi, StaticVarApiImpl, VMApi,
const_handles, EndpointArgumentApi, EndpointArgumentApiImpl, ErrorApi, ErrorApiImpl,
ManagedTypeApi, StaticVarApiImpl, VMApi,
},
codec::{DecodeError, TopDecodeMulti, TopDecodeMultiInput},
err_msg,
io::{ArgErrorHandler, ArgId},
types::{ManagedArgBuffer, ManagedBuffer, ManagedType},
types::{ManagedArgBuffer, ManagedBuffer, ManagedType, ManagedVecRefIterator},
};

/// Argument count cannot change during execution, and it can get queried multiple times,
Expand Down Expand Up @@ -194,19 +194,16 @@ where
N::next_multi_arg(loader, arg_names)
}

fn callback_closure_args_loader<AA>() -> ManagedResultArgLoader<AA>
fn callback_closure_args_loader<AA>() -> ManagedVecRefIterator<'static, AA, ManagedBuffer<AA>>
where
AA: VMApi,
{
let cb_closure_args_serialized = ManagedBuffer::<AA>::new();
AA::argument_api_impl().load_callback_closure_buffer(cb_closure_args_serialized.get_handle());
unsafe {
AA::argument_api_impl()
.load_callback_closure_buffer(use_raw_handle(const_handles::MBUF_TEMPORARY_1));
let cb_closure_args_serialized =
ManagedBuffer::<AA>::from_raw_handle(const_handles::MBUF_TEMPORARY_1);
let mut cb_closure_args_buffer =
ManagedArgBuffer::<AA>::from_raw_handle(const_handles::CALLBACK_CLOSURE_ARGS_BUFFER);
cb_closure_args_buffer.deserialize_overwrite(cb_closure_args_serialized);

ManagedResultArgLoader::new(cb_closure_args_buffer.into_vec_of_buffers())
ManagedVecRefIterator::new_from_handle(cb_closure_args_buffer.forget_into_handle())
}
}
52 changes: 0 additions & 52 deletions framework/base/src/io/managed_result_arg_loader.rs

This file was deleted.

7 changes: 3 additions & 4 deletions framework/base/src/types/interaction/callback_closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ use crate::{
},
contract_base::{BlockchainWrapper, ExitCodecErrorHandler, ManagedSerializer},
err_msg,
io::ManagedResultArgLoader,
storage::StorageKey,
storage_clear, storage_get, storage_set,
types::{ManagedBuffer, ManagedType},
types::{ManagedBuffer, ManagedType, ManagedVecRefIterator},
};

use super::ManagedArgBuffer;
Expand Down Expand Up @@ -125,8 +124,8 @@ impl<M: ManagedTypeApi + ErrorApi> CallbackClosureForDeser<M> {
CallbackClosureMatcher::new(&self.callback_name)
}

pub fn into_arg_loader(self) -> ManagedResultArgLoader<M> {
ManagedResultArgLoader::new(self.closure_args.data)
pub fn arg_iter(&self) -> ManagedVecRefIterator<'_, M, ManagedBuffer<M>> {
self.closure_args.iter_buffers()
}
}

Expand Down
18 changes: 9 additions & 9 deletions framework/base/src/types/interaction/callback_selector_result.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use crate::api::{ErrorApi, ManagedTypeApi};

use super::CallbackClosureForDeser;

/// Used internally between the `callback` and `callback_selector` methods.
/// It is likely to be removed in the future.
pub enum CallbackSelectorResult<A>
where
A: ManagedTypeApi + ErrorApi,
{
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum CallbackSelectorResult {
Processed,
NotProcessed(CallbackClosureForDeser<A>),
NotProcessed,
}

impl CallbackSelectorResult {
pub fn is_processed(self) -> bool {
matches!(self, CallbackSelectorResult::Processed)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
api::{BlockchainApiImpl, CallTypeApi},
contract_base::{ExitCodecErrorHandler, SendRawWrapper},
err_msg,
io::{ArgErrorHandler, ArgId, ManagedResultArgLoader},
io::{ArgErrorHandler, ArgId},
types::{
BigUint, CodeMetadata, ManagedAddress, ManagedArgBuffer, ManagedBuffer, ManagedOption,
ManagedVec,
Expand Down Expand Up @@ -112,7 +112,7 @@ where
where
RequestedResult: TopDecodeMulti + TypeAbiFrom<OriginalResult>,
{
let mut loader = ManagedResultArgLoader::new(raw_result);
let mut loader = raw_result.into_iter();
let arg_id = ArgId::from(&b"init result"[..]);
let h = ArgErrorHandler::<SA>::from(arg_id);
RequestedResult::multi_decode_or_handle_err(&mut loader, h).unwrap_infallible()
Expand Down
4 changes: 2 additions & 2 deletions framework/base/src/types/interaction/tx_exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use unwrap_infallible::UnwrapInfallible;

use crate::{
api::CallTypeApi,
io::{ArgErrorHandler, ArgId, ManagedResultArgLoader},
io::{ArgErrorHandler, ArgId},
types::{ManagedBuffer, ManagedVec},
};
use multiversx_sc_codec::TopDecodeMulti;
Expand All @@ -30,7 +30,7 @@ where
SA: CallTypeApi + 'static,
RequestedResult: TopDecodeMulti,
{
let mut loader = ManagedResultArgLoader::new(raw_result);
let mut loader = raw_result.into_iter();
let arg_id = ArgId::from(&b"sync result"[..]);
let h: ArgErrorHandler<SA> = ArgErrorHandler::<SA>::from(arg_id);
RequestedResult::multi_decode_or_handle_err(&mut loader, h).unwrap_infallible()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ use unwrap_infallible::UnwrapInfallible;

use crate::codec::{TopDecodeMulti, TopDecodeMultiInput};

use crate::types::{ManagedBuffer, ManagedVec};
use crate::types::{ManagedBuffer, ManagedVec, ManagedVecOwnedIterator};
use crate::{
api::{ErrorApi, ManagedTypeApi},
io::{ArgErrorHandler, ArgId, ManagedResultArgLoader},
io::{ArgErrorHandler, ArgId},
};

/// Iterator for `MultiValueEncoded` and `MultiValueEncodedCounted`.
Expand All @@ -18,7 +18,7 @@ where
M: ManagedTypeApi + ErrorApi,
T: TopDecodeMulti,
{
data_loader: ManagedResultArgLoader<M>,
data_loader: ManagedVecOwnedIterator<M, ManagedBuffer<M>>,
_phantom: PhantomData<T>,
}

Expand All @@ -29,7 +29,7 @@ where
{
pub(crate) fn new(raw_buffers: ManagedVec<M, ManagedBuffer<M>>) -> Self {
MultiValueEncodedIterator {
data_loader: ManagedResultArgLoader::new(raw_buffers),
data_loader: raw_buffers.into_iter(),
_phantom: PhantomData,
}
}
Expand All @@ -43,14 +43,13 @@ where
type Item = T;

fn next(&mut self) -> Option<T> {
if self.data_loader.has_next() {
let arg_id = ArgId::from(&b"var args"[..]);
let h = ArgErrorHandler::<M>::from(arg_id);
let result =
T::multi_decode_or_handle_err(&mut self.data_loader, h).unwrap_infallible();
Some(result)
} else {
None
if !self.data_loader.has_next() {
return None;
}

let arg_id = ArgId::from(&b"var args"[..]);
let h = ArgErrorHandler::<M>::from(arg_id);
let result = T::multi_decode_or_handle_err(&mut self.data_loader, h).unwrap_infallible();
Some(result)
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
use crate::{api::ManagedTypeApi, types::ManagedType};
use multiversx_sc_codec::{DecodeError, DecodeErrorHandler, TopDecodeMultiInput};

use crate::{
api::{ErrorApi, ManagedTypeApi},
types::{ManagedBuffer, ManagedType},
};

use super::{ManagedVec, ManagedVecItem, ManagedVecPayloadIterator};

Expand Down Expand Up @@ -34,6 +39,10 @@ where
}
}
}

pub(crate) fn iter_is_empty(&self) -> bool {
self.payload_iter.iter_is_empty()
}
}

impl<M, T> Iterator for ManagedVecOwnedIterator<M, T>
Expand Down Expand Up @@ -70,3 +79,25 @@ where
Some(T::read_from_payload(&payload))
}
}

impl<A> TopDecodeMultiInput for ManagedVecOwnedIterator<A, ManagedBuffer<A>>
where
A: ManagedTypeApi + ErrorApi,
{
type ValueInput = ManagedBuffer<A>;

fn has_next(&self) -> bool {
!self.iter_is_empty()
}

fn next_value_input<H>(&mut self, h: H) -> Result<Self::ValueInput, H::HandledErr>
where
H: DecodeErrorHandler,
{
if let Some(buffer) = self.next() {
Ok(buffer)
} else {
Err(h.handle_error(DecodeError::MULTI_TOO_FEW_ARGS))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ where
_phantom: PhantomData,
}
}

pub(crate) fn remaining(&self) -> usize {
(self.byte_end - self.byte_start) / P::payload_size()
}

/// TODO: can be replaced with ExactSizeIterator::is_empty once it's stabilized
pub(crate) fn iter_is_empty(&self) -> bool {
self.byte_start >= self.byte_end
}
}

impl<M, P> Iterator for ManagedVecPayloadIterator<M, P>
Expand All @@ -50,10 +59,10 @@ where
type Item = P;

fn next(&mut self) -> Option<P> {
let next_byte_start = self.byte_start + P::payload_size();
if next_byte_start > self.byte_end {
if self.iter_is_empty() {
return None;
}
let next_byte_start = self.byte_start + P::payload_size();

let mut payload = P::new_buffer();
let _ = M::managed_type_impl().mb_load_slice(
Expand All @@ -67,8 +76,7 @@ where
}

fn size_hint(&self) -> (usize, Option<usize>) {
let size = P::payload_size();
let remaining = (self.byte_end - self.byte_start) / size;
let remaining = self.remaining();
(remaining, Some(remaining))
}
}
Expand All @@ -78,6 +86,9 @@ where
M: ManagedTypeApi,
P: ManagedVecItemPayload,
{
fn len(&self) -> usize {
self.remaining()
}
}

impl<M, P> DoubleEndedIterator for ManagedVecPayloadIterator<M, P>
Expand All @@ -86,7 +97,7 @@ where
P: ManagedVecItemPayload,
{
fn next_back(&mut self) -> Option<Self::Item> {
if self.byte_start + P::payload_size() > self.byte_end {
if self.iter_is_empty() {
return None;
}
self.byte_end -= P::payload_size();
Expand Down
Loading

0 comments on commit bef75c5

Please sign in to comment.