pub trait WasmType: PartialEq<crate::Type> + PartialEq + Eq {
fn to_parser_type(&self) -> crate::Type;
}
pub trait WasmFuncType {
type Type: WasmType;
fn len_inputs(&self) -> usize;
fn len_outputs(&self) -> usize;
fn input_at(&self, at: u32) -> Option<&Self::Type>;
fn output_at(&self, at: u32) -> Option<&Self::Type>;
}
pub(crate) struct WasmFuncTypeInputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
func_type: &'a F,
start: u32,
end: u32,
}
impl<'a, F, T> WasmFuncTypeInputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
fn new(func_type: &'a F) -> Self {
Self {
func_type,
start: 0,
end: func_type.len_inputs() as u32,
}
}
}
impl<'a, F, T> Iterator for WasmFuncTypeInputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
if self.start == self.end {
return None;
}
let ty = self
.func_type
.input_at(self.start)
.expect("we expect to receive an input type at this point");
self.start += 1;
Some(ty)
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len(), Some(self.len()))
}
}
impl<'a, F, T> DoubleEndedIterator for WasmFuncTypeInputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
fn next_back(&mut self) -> Option<Self::Item> {
if self.start == self.end {
return None;
}
let ty = self
.func_type
.input_at(self.end)
.expect("we expect to receive an input type at this point");
self.end -= 1;
Some(ty)
}
}
impl<'a, F, T> ExactSizeIterator for WasmFuncTypeInputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
fn len(&self) -> usize {
(self.end as usize) - (self.start as usize)
}
}
pub(crate) struct WasmFuncTypeOutputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
func_type: &'a F,
start: u32,
end: u32,
}
impl<'a, F, T> WasmFuncTypeOutputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
fn new(func_type: &'a F) -> Self {
Self {
func_type,
start: 0,
end: func_type.len_outputs() as u32,
}
}
}
impl<'a, F, T> Iterator for WasmFuncTypeOutputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
if self.start == self.end {
return None;
}
let ty = self
.func_type
.output_at(self.start)
.expect("we expect to receive an input type at this point");
self.start += 1;
Some(ty)
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len(), Some(self.len()))
}
}
impl<'a, F, T> DoubleEndedIterator for WasmFuncTypeOutputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
fn next_back(&mut self) -> Option<Self::Item> {
if self.start == self.end {
return None;
}
let ty = self
.func_type
.output_at(self.end)
.expect("we expect to receive an input type at this point");
self.end -= 1;
Some(ty)
}
}
impl<'a, F, T> ExactSizeIterator for WasmFuncTypeOutputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
fn len(&self) -> usize {
(self.end as usize) - (self.start as usize)
}
}
pub(crate) fn wasm_func_type_inputs<'a, F, T>(func_type: &'a F) -> WasmFuncTypeInputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
WasmFuncTypeInputs::new(func_type)
}
pub(crate) fn wasm_func_type_outputs<'a, F, T>(func_type: &'a F) -> WasmFuncTypeOutputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
WasmFuncTypeOutputs::new(func_type)
}
pub trait WasmTableType {
type Type: WasmType;
fn element_type(&self) -> &Self::Type;
fn initial_limit(&self) -> u32;
fn maximum_limit(&self) -> Option<u32>;
}
pub trait WasmMemoryType {
fn is_shared(&self) -> bool;
fn initial_limit(&self) -> u32;
fn maximum_limit(&self) -> Option<u32>;
}
pub trait WasmGlobalType {
type Type: WasmType;
fn is_mutable(&self) -> bool;
fn content_type(&self) -> &Self::Type;
}
pub trait WasmModuleResources {
type FuncType: WasmFuncType;
type TableType: WasmTableType;
type MemoryType: WasmMemoryType;
type GlobalType: WasmGlobalType;
fn type_at(&self, at: u32) -> Option<&Self::FuncType>;
fn table_at(&self, at: u32) -> Option<&Self::TableType>;
fn memory_at(&self, at: u32) -> Option<&Self::MemoryType>;
fn global_at(&self, at: u32) -> Option<&Self::GlobalType>;
fn func_type_id_at(&self, at: u32) -> Option<u32>;
fn element_type_at(&self, at: u32) -> Option<crate::Type>;
fn element_count(&self) -> u32;
fn data_count(&self) -> u32;
fn is_function_referenced(&self, idx: u32) -> bool;
}
impl<T> WasmModuleResources for &'_ T
where
T: ?Sized + WasmModuleResources,
{
type FuncType = T::FuncType;
type TableType = T::TableType;
type MemoryType = T::MemoryType;
type GlobalType = T::GlobalType;
fn type_at(&self, at: u32) -> Option<&Self::FuncType> {
T::type_at(self, at)
}
fn table_at(&self, at: u32) -> Option<&Self::TableType> {
T::table_at(self, at)
}
fn memory_at(&self, at: u32) -> Option<&Self::MemoryType> {
T::memory_at(self, at)
}
fn global_at(&self, at: u32) -> Option<&Self::GlobalType> {
T::global_at(self, at)
}
fn func_type_id_at(&self, at: u32) -> Option<u32> {
T::func_type_id_at(self, at)
}
fn element_type_at(&self, at: u32) -> Option<crate::Type> {
T::element_type_at(self, at)
}
fn element_count(&self) -> u32 {
T::element_count(self)
}
fn data_count(&self) -> u32 {
T::data_count(self)
}
fn is_function_referenced(&self, idx: u32) -> bool {
T::is_function_referenced(self, idx)
}
}
impl WasmType for crate::Type {
fn to_parser_type(&self) -> crate::Type {
*self
}
}
impl WasmFuncType for crate::FuncType {
type Type = crate::Type;
fn len_inputs(&self) -> usize {
self.params.len()
}
fn len_outputs(&self) -> usize {
self.returns.len()
}
fn input_at(&self, at: u32) -> Option<&Self::Type> {
self.params.get(at as usize)
}
fn output_at(&self, at: u32) -> Option<&Self::Type> {
self.returns.get(at as usize)
}
}
impl WasmGlobalType for crate::GlobalType {
type Type = crate::Type;
fn is_mutable(&self) -> bool {
self.mutable
}
fn content_type(&self) -> &Self::Type {
&self.content_type
}
}
impl WasmTableType for crate::TableType {
type Type = crate::Type;
fn element_type(&self) -> &Self::Type {
&self.element_type
}
fn initial_limit(&self) -> u32 {
self.limits.initial
}
fn maximum_limit(&self) -> Option<u32> {
self.limits.maximum
}
}
impl WasmMemoryType for crate::MemoryType {
fn is_shared(&self) -> bool {
self.shared
}
fn initial_limit(&self) -> u32 {
self.limits.initial
}
fn maximum_limit(&self) -> Option<u32> {
self.limits.maximum
}
}