use alloc::boxed::Box;
use crate::{Shared, TypeAddr, WasmType};
#[derive(Clone, PartialEq, Eq, Default)]
#[cfg_attr(feature = "debug", derive(Debug))]
#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))]
pub struct TypeSection {
pub types: Box<[SubType]>,
pub rec_group_lengths: Box<[u32]>,
}
impl TypeSection {
#[inline]
pub fn get(&self, index: TypeAddr) -> Option<&SubType> {
self.types.get(index as usize)
}
#[inline]
pub fn len(&self) -> usize {
self.types.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.types.is_empty()
}
}
#[derive(Clone, PartialEq, Eq)]
#[cfg_attr(feature = "debug", derive(Debug))]
#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))]
pub struct SubType {
pub is_final: bool,
pub supertype: Option<TypeAddr>,
pub composite: CompositeType,
}
impl SubType {
#[inline]
pub const fn as_func(&self) -> Option<&FuncType> {
self.composite.as_func()
}
#[inline]
pub const fn as_struct(&self) -> Option<&StructType> {
self.composite.as_struct()
}
#[inline]
pub const fn as_array(&self) -> Option<&ArrayType> {
self.composite.as_array()
}
}
#[derive(Clone, PartialEq, Eq)]
#[cfg_attr(feature = "debug", derive(Debug))]
#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))]
pub enum CompositeType {
Func(FuncType),
Struct(StructType),
Array(ArrayType),
}
impl CompositeType {
#[inline]
pub const fn as_func(&self) -> Option<&FuncType> {
match self {
Self::Func(ty) => Some(ty),
_ => None,
}
}
#[inline]
pub const fn as_struct(&self) -> Option<&StructType> {
match self {
Self::Struct(ty) => Some(ty),
_ => None,
}
}
#[inline]
pub const fn as_array(&self) -> Option<&ArrayType> {
match self {
Self::Array(ty) => Some(ty),
_ => None,
}
}
}
#[derive(Clone, PartialEq, Eq, Default)]
#[cfg_attr(feature = "debug", derive(Debug))]
#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))]
pub struct FuncType {
data: Shared<[WasmType]>,
param_count: u16,
}
impl FuncType {
pub fn new(params: &[WasmType], results: &[WasmType]) -> Self {
let data: Box<[WasmType]> = params.iter().cloned().chain(results.iter().cloned()).collect();
Self { data: data.into(), param_count: params.len() as u16 }
}
pub fn params(&self) -> &[WasmType] {
&self.data[..self.param_count as usize]
}
pub fn results(&self) -> &[WasmType] {
&self.data[self.param_count as usize..]
}
}
#[derive(Clone, PartialEq, Eq, Default)]
#[cfg_attr(feature = "debug", derive(Debug))]
#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))]
pub struct StructType {
pub fields: Box<[FieldType]>,
}
#[derive(Clone, PartialEq, Eq)]
#[cfg_attr(feature = "debug", derive(Debug))]
#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))]
pub struct ArrayType {
pub field: FieldType,
}
#[derive(Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "debug", derive(Debug))]
#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))]
pub struct FieldType {
pub storage: StorageType,
pub mutable: bool,
}
#[derive(Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "debug", derive(Debug))]
#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))]
pub enum StorageType {
I8,
I16,
Value(WasmType),
}
impl StorageType {
pub const fn unpacked(self) -> WasmType {
match self {
Self::I8 | Self::I16 => WasmType::I32,
Self::Value(ty) => ty,
}
}
}