use wasefire_protocol::applet::ExitStatus;
use crate::{Error, Trap};
pub trait Api: Send {
type Install: crate::transfer::Api;
unsafe fn get() -> Result<&'static [u8], Error>;
fn notify_start() {}
fn notify_exit(status: ExitStatus) {
let _ = status;
}
}
pub type Install<B> = <super::Applet<B> as Api>::Install;
pub trait Memory {
fn get(&self, ptr: u32, len: u32) -> Result<&[u8], Trap>;
#[allow(clippy::mut_from_ref)]
fn get_mut(&self, ptr: u32, len: u32) -> Result<&mut [u8], Trap>;
fn alloc(&mut self, size: u32, align: u32) -> Result<u32, Trap>;
}
pub trait MemoryExt: Memory {
fn get_opt(&self, ptr: u32, len: u32) -> Result<Option<&[u8]>, Trap> {
Ok(match ptr {
0 => None,
_ => Some(self.get(ptr, len)?),
})
}
fn get_array<const LEN: usize>(&self, ptr: u32) -> Result<&[u8; LEN], Trap> {
self.get(ptr, LEN as u32).map(|x| x.try_into().unwrap())
}
fn get_array_mut<const LEN: usize>(&self, ptr: u32) -> Result<&mut [u8; LEN], Trap> {
self.get_mut(ptr, LEN as u32).map(|x| x.try_into().unwrap())
}
#[allow(clippy::wrong_self_convention)]
fn from_bytes<T: bytemuck::AnyBitPattern>(&self, ptr: u32) -> Result<&T, Trap> {
bytemuck::try_from_bytes(self.get(ptr, core::mem::size_of::<T>() as u32)?).map_err(|_| Trap)
}
#[allow(clippy::wrong_self_convention)]
fn from_bytes_mut<T: bytemuck::NoUninit + bytemuck::AnyBitPattern>(
&self, ptr: u32,
) -> Result<&mut T, Trap> {
bytemuck::try_from_bytes_mut(self.get_mut(ptr, core::mem::size_of::<T>() as u32)?)
.map_err(|_| Trap)
}
fn alloc_copy(&mut self, ptr_ptr: u32, len_ptr: Option<u32>, data: &[u8]) -> Result<u32, Trap> {
let len = data.len() as u32;
if 0 < len {
let ptr = self.alloc(len, 1)?;
self.get_mut(ptr, len)?.copy_from_slice(data);
self.get_mut(ptr_ptr, 4)?.copy_from_slice(&ptr.to_le_bytes());
}
if let Some(len_ptr) = len_ptr {
self.get_mut(len_ptr, 4)?.copy_from_slice(&len.to_le_bytes());
}
Ok(len)
}
}
impl<T: Memory> MemoryExt for T {}
#[cfg(feature = "api-vendor")]
pub trait Handlers<Key> {
fn register(&mut self, key: Key, func: u32, data: u32) -> Result<(), Trap>;
fn unregister(&mut self, key: Key) -> Result<(), Trap>;
}