use crate::{__private::wasip1::*, memory::WasmAccessName};
#[cfg(target_os = "wasi")]
use const_for::const_for;
use const_struct::*;
use crate::memory::WasmAccess;
#[macro_export]
macro_rules! plug_args {
(@embedded, $ty:ty, $($wasm:ident),* $(,)?) => {
$crate::__as_t!(@through, $($wasm),* => $crate::plug_args, @inner, @embedded, $ty);
};
(@dynamic, $state:expr, $($wasm:ident),* $(,)?) => {
$crate::__as_t!(@through, $($wasm),* => $crate::plug_args, @inner, @dynamic, $state);
};
(@inner, @embedded, $ty:ty, $($wasm:ident),*) => {
const _: () = {
type __TYPE = $ty;
$crate::__private::paste::paste! {
$(
const _: () = {
$crate::__as_t!(@as_t, $wasm);
#[unsafe(no_mangle)]
#[cfg(target_os = "wasi")]
pub unsafe extern "C" fn [<__wasip1_vfs_ $wasm _args_sizes_get>](
__args_count: *mut $crate::__private::wasip1::Size,
__args_buf_size: *mut $crate::__private::wasip1::Size,
) -> $crate::__private::wasip1::Errno {
$crate::__private::inner::args::args_sizes_get_embedded_inner::<__TYPE, T>(__args_count, __args_buf_size)
}
#[cfg(target_os = "wasi")]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn [<__wasip1_vfs_ $wasm _args_get>](
__args: *mut *const u8,
__args_buf: *mut u8,
) -> $crate::__private::wasip1::Errno {
$crate::__private::inner::args::args_get_embedded_inner::<__TYPE, T>(__args, __args_buf)
}
};
)*
}
};
};
(@inner, @dynamic, $state:expr, $($wasm:ident),*) => {
const _: () = {
let _ = || {
let _ = $state;
};
};
$crate::__private::paste::paste! {
$(
#[cfg(target_os = "wasi")]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn [<__wasip1_vfs_ $wasm _args_sizes_get>](
__args_count: *mut $crate::__private::wasip1::Size,
__args_buf_size: *mut $crate::__private::wasip1::Size,
) -> $crate::__private::wasip1::Errno {
$crate::__as_t!(@as_t, $wasm);
let state = $state;
$crate::__private::inner::args::args_sizes_get_inner::<T>(state, __args_count, __args_buf_size)
}
#[cfg(target_os = "wasi")]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn [<__wasip1_vfs_ $wasm _args_get>](
__args: *mut *const u8,
__args_buf: *mut u8,
) -> $crate::__private::wasip1::Errno {
$crate::__as_t!(@as_t, $wasm);
let state = $state;
$crate::__private::inner::args::args_get_inner::<T>(state, __args, __args_buf)
}
)*
}
};
}
#[const_struct]
pub struct VirtualArgsEmbeddedState {
pub args: &'static [&'static str],
}
#[inline]
#[cfg(target_os = "wasi")]
pub fn args_sizes_get_embedded_inner<
T: PrimitiveTraits<DATATYPE = VirtualArgsEmbeddedState>,
Wasm: WasmAccess,
>(
args_count: *mut Size,
args_buf_size: *mut Size,
) -> Errno {
const fn inner<T: PrimitiveTraits<DATATYPE = VirtualArgsEmbeddedState>>() -> (Size, Size) {
let mut size = 0;
let mut count = 0;
const_for!(i in 0..T::__DATA.args.len() => {
let len = T::__DATA.args[i].len() + 1; size += len;
count += 1;
});
(size, count)
}
Wasm::store_le(args_buf_size, inner::<T>().0);
Wasm::store_le(args_count, inner::<T>().1);
ERRNO_SUCCESS
}
#[inline]
#[cfg(target_os = "wasi")]
pub fn args_get_embedded_inner<
T: PrimitiveTraits<DATATYPE = VirtualArgsEmbeddedState>,
Wasm: WasmAccess,
>(
args: *mut *const u8,
args_buf: *mut u8,
) -> Errno {
let mut args = args;
let mut args_buf = args_buf;
const_for!(i in 0..T::__DATA.args.len() => {
Wasm::store_le(args, args_buf as *const u8);
Wasm::memcpy(args_buf, T::__DATA.args[i].as_bytes());
Wasm::store_le(unsafe { args_buf.add(T::__DATA.args[i].len()) }, 0u8);
args = unsafe { args.add(1) };
args_buf = unsafe { args_buf.add(T::__DATA.args[i].len() + 1) };
});
ERRNO_SUCCESS
}
#[inline]
#[cfg(target_os = "wasi")]
pub fn args_sizes_get_const_inner<
T: PrimitiveTraits<DATATYPE = VirtualArgsEmbeddedState>,
Wasm: WasmAccess,
>(
args_count: *mut Size,
args_buf_size: *mut Size,
) -> Errno {
const fn inner<T: PrimitiveTraits<DATATYPE = VirtualArgsEmbeddedState>>() -> (Size, Size) {
let mut size = 0;
let mut count = 0;
const_for!(i in 0..T::__DATA.args.len() => {
let len = T::__DATA.args[i].len() + 1; size += len;
count += 1;
});
(size, count)
}
Wasm::store_le(args_buf_size, inner::<T>().0);
Wasm::store_le(args_count, inner::<T>().1);
ERRNO_SUCCESS
}
#[inline]
#[cfg(target_os = "wasi")]
pub fn args_get_const_inner<
T: PrimitiveTraits<DATATYPE = VirtualArgsEmbeddedState>,
Wasm: WasmAccess,
>(
args: *mut *const u8,
args_buf: *mut u8,
) -> Errno {
let mut args = args;
let mut args_buf = args_buf;
const_for!(i in 0..T::__DATA.args.len() => {
Wasm::store_le(args, args_buf as *const u8);
Wasm::memcpy(args_buf, T::__DATA.args[i].as_bytes());
Wasm::store_le(unsafe { args_buf.add(T::__DATA.args[i].len()) }, 0u8);
args = unsafe { args.add(1) };
args_buf = unsafe { args_buf.add(T::__DATA.args[i].len() + 1) };
});
ERRNO_SUCCESS
}
pub trait VirtualArgs<'a> {
type Str: AsRef<str>;
fn get_args(&'a mut self) -> &'a [Self::Str];
fn args_sizes_get(&'a mut self) -> (Size, Size) {
let args = self.get_args();
let mut size = 0;
let mut count = 0;
for arg in args {
let len = arg.as_ref().len() + 1; size += len;
count += 1;
}
(size, count)
}
fn args_get<Wasm: WasmAccess + WasmAccessName + 'static>(
&'a mut self,
args: *mut *const u8,
args_buf: *mut u8,
) -> Errno {
let mut args = args;
let mut args_buf = args_buf;
for arg in self.get_args() {
Wasm::store_le(args, args_buf as *const u8);
Wasm::memcpy(args_buf, arg.as_ref().as_bytes());
Wasm::store_le(unsafe { args_buf.add(arg.as_ref().len()) as *mut u8 }, 0u8);
args = unsafe { args.add(1) };
args_buf = unsafe { args_buf.add(arg.as_ref().len() + 1) };
}
ERRNO_SUCCESS
}
}
impl<'a, T: core::ops::DerefMut<Target = U>, U: VirtualArgs<'a> + 'a> VirtualArgs<'a> for T {
type Str = U::Str;
fn get_args(&'a mut self) -> &'a [Self::Str] {
self.deref_mut().get_args()
}
fn args_sizes_get(&'a mut self) -> (Size, Size) {
self.deref_mut().args_sizes_get()
}
}
#[cfg(target_os = "wasi")]
pub fn args_sizes_get_inner<'a, Wasm: WasmAccess + WasmAccessName + 'static>(
state: &'a mut impl VirtualArgs<'a>,
args_count: *mut Size,
args_buf_size: *mut Size,
) -> Errno {
let (size, count) = state.args_sizes_get();
Wasm::store_le(args_buf_size, size);
Wasm::store_le(args_count, count);
ERRNO_SUCCESS
}
#[inline]
#[cfg(target_os = "wasi")]
pub fn args_get_inner<'a, Wasm: WasmAccess + WasmAccessName + 'static>(
state: &'a mut impl VirtualArgs<'a>,
args: *mut *const u8,
args_buf: *mut u8,
) -> Errno {
state.args_get::<Wasm>(args, args_buf)
}