Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: ManagedResultArgLoader replaced with ManagedVec iterators #1899

Merged
merged 7 commits into from
Dec 12, 2024
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
Loading