use super::super::alloc;
use super::types::{self, CommittedAlloc, StagedAlloc};
use crate::guest::alloc::{Allocator, Collector, Commit};
use crate::Result;
use core::ffi::c_long;
pub unsafe trait Alloc<'a> {
const NUM: c_long;
type Argv: Into<[usize; 6]>;
type Ret;
type Staged: Commit<Item = Self::Committed>;
type Committed;
type Collected;
fn stage(self, alloc: &mut impl Allocator) -> Result<(Self::Argv, Self::Staged)>;
fn collect(
committed: Self::Committed,
ret: Result<Self::Ret>,
col: &impl Collector,
) -> Self::Collected;
}
impl<'a, T: Alloc<'a>> super::super::Alloc<'a, alloc::kind::Syscall> for T
where
types::Result<T::Ret>: Into<Result<T::Ret>>,
{
type Staged = StagedAlloc<'a, T>;
type Committed = CommittedAlloc<'a, T>;
type Collected = T::Collected;
#[inline]
fn stage(self, alloc: &mut impl Allocator) -> Result<Self::Staged> {
let num_ref = alloc.allocate_input()?;
let argv_ref = alloc.allocate_input()?;
let ret_ref = alloc.allocate_inout()?;
let ((argv, staged), _) = alloc.section(|alloc| self.stage(alloc))?;
Ok(Self::Staged {
num_ref,
argv: argv_ref.stage(argv.into()),
ret_ref,
staged,
})
}
}