use crate::{
types::CoreTypeId, BinaryReaderError, FuncType, GlobalType, HeapType, MemoryType, RefType,
SubType, TableType, ValType, WasmFeatures,
};
pub trait WasmModuleResources {
fn table_at(&self, at: u32) -> Option<TableType>;
fn memory_at(&self, at: u32) -> Option<MemoryType>;
fn tag_at(&self, at: u32) -> Option<&FuncType>;
fn global_at(&self, at: u32) -> Option<GlobalType>;
fn sub_type_at(&self, type_index: u32) -> Option<&SubType>;
fn sub_type_at_id(&self, id: CoreTypeId) -> &SubType;
fn type_id_of_function(&self, func_idx: u32) -> Option<CoreTypeId>;
fn type_index_of_function(&self, func_index: u32) -> Option<u32>;
fn element_type_at(&self, at: u32) -> Option<RefType>;
fn is_subtype(&self, a: ValType, b: ValType) -> bool;
fn is_shared(&self, ty: RefType) -> bool;
fn check_value_type(
&self,
t: &mut ValType,
features: &WasmFeatures,
offset: usize,
) -> Result<(), BinaryReaderError> {
features
.check_value_type(*t)
.map_err(|s| BinaryReaderError::new(s, offset))?;
match t {
ValType::Ref(r) => self.check_ref_type(r, offset),
ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 | ValType::V128 => Ok(()),
}
}
fn check_ref_type(
&self,
ref_type: &mut RefType,
offset: usize,
) -> Result<(), BinaryReaderError> {
let is_nullable = ref_type.is_nullable();
let mut heap_ty = ref_type.heap_type();
self.check_heap_type(&mut heap_ty, offset)?;
*ref_type = RefType::new(is_nullable, heap_ty).unwrap();
Ok(())
}
fn check_heap_type(
&self,
heap_type: &mut HeapType,
offset: usize,
) -> Result<(), BinaryReaderError>;
fn top_type(&self, heap_type: &HeapType) -> HeapType;
fn element_count(&self) -> u32;
fn data_count(&self) -> Option<u32>;
fn is_function_referenced(&self, idx: u32) -> bool;
}
impl<T> WasmModuleResources for &'_ T
where
T: ?Sized + WasmModuleResources,
{
fn table_at(&self, at: u32) -> Option<TableType> {
T::table_at(self, at)
}
fn memory_at(&self, at: u32) -> Option<MemoryType> {
T::memory_at(self, at)
}
fn tag_at(&self, at: u32) -> Option<&FuncType> {
T::tag_at(self, at)
}
fn global_at(&self, at: u32) -> Option<GlobalType> {
T::global_at(self, at)
}
fn sub_type_at(&self, at: u32) -> Option<&SubType> {
T::sub_type_at(self, at)
}
fn sub_type_at_id(&self, at: CoreTypeId) -> &SubType {
T::sub_type_at_id(self, at)
}
fn type_id_of_function(&self, func_idx: u32) -> Option<CoreTypeId> {
T::type_id_of_function(self, func_idx)
}
fn type_index_of_function(&self, func_idx: u32) -> Option<u32> {
T::type_index_of_function(self, func_idx)
}
fn check_heap_type(&self, t: &mut HeapType, offset: usize) -> Result<(), BinaryReaderError> {
T::check_heap_type(self, t, offset)
}
fn top_type(&self, heap_type: &HeapType) -> HeapType {
T::top_type(self, heap_type)
}
fn element_type_at(&self, at: u32) -> Option<RefType> {
T::element_type_at(self, at)
}
fn is_subtype(&self, a: ValType, b: ValType) -> bool {
T::is_subtype(self, a, b)
}
fn is_shared(&self, ty: RefType) -> bool {
T::is_shared(self, ty)
}
fn element_count(&self) -> u32 {
T::element_count(self)
}
fn data_count(&self) -> Option<u32> {
T::data_count(self)
}
fn is_function_referenced(&self, idx: u32) -> bool {
T::is_function_referenced(self, idx)
}
}
impl<T> WasmModuleResources for alloc::sync::Arc<T>
where
T: WasmModuleResources,
{
fn table_at(&self, at: u32) -> Option<TableType> {
T::table_at(self, at)
}
fn memory_at(&self, at: u32) -> Option<MemoryType> {
T::memory_at(self, at)
}
fn tag_at(&self, at: u32) -> Option<&FuncType> {
T::tag_at(self, at)
}
fn global_at(&self, at: u32) -> Option<GlobalType> {
T::global_at(self, at)
}
fn sub_type_at(&self, type_idx: u32) -> Option<&SubType> {
T::sub_type_at(self, type_idx)
}
fn sub_type_at_id(&self, id: CoreTypeId) -> &SubType {
T::sub_type_at_id(self, id)
}
fn type_id_of_function(&self, func_idx: u32) -> Option<CoreTypeId> {
T::type_id_of_function(self, func_idx)
}
fn type_index_of_function(&self, func_idx: u32) -> Option<u32> {
T::type_index_of_function(self, func_idx)
}
fn check_heap_type(&self, t: &mut HeapType, offset: usize) -> Result<(), BinaryReaderError> {
T::check_heap_type(self, t, offset)
}
fn top_type(&self, heap_type: &HeapType) -> HeapType {
T::top_type(self, heap_type)
}
fn element_type_at(&self, at: u32) -> Option<RefType> {
T::element_type_at(self, at)
}
fn is_subtype(&self, a: ValType, b: ValType) -> bool {
T::is_subtype(self, a, b)
}
fn is_shared(&self, ty: RefType) -> bool {
T::is_shared(self, ty)
}
fn element_count(&self) -> u32 {
T::element_count(self)
}
fn data_count(&self) -> Option<u32> {
T::data_count(self)
}
fn is_function_referenced(&self, idx: u32) -> bool {
T::is_function_referenced(self, idx)
}
}