1use alloc::boxed::Box;
2
3use crate::{Shared, TypeAddr, WasmType};
4
5#[derive(Clone, PartialEq, Eq, Default)]
9#[cfg_attr(feature = "debug", derive(Debug))]
10#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))]
11pub struct TypeSection {
12 pub types: Box<[SubType]>,
14 pub rec_group_lengths: Box<[u32]>,
16}
17
18impl TypeSection {
19 #[inline]
20 pub fn get(&self, index: TypeAddr) -> Option<&SubType> {
21 self.types.get(index as usize)
22 }
23
24 #[inline]
25 pub fn len(&self) -> usize {
26 self.types.len()
27 }
28
29 #[inline]
30 pub fn is_empty(&self) -> bool {
31 self.types.is_empty()
32 }
33}
34
35#[derive(Clone, PartialEq, Eq)]
39#[cfg_attr(feature = "debug", derive(Debug))]
40#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))]
41pub struct SubType {
42 pub is_final: bool,
43 pub supertype: Option<TypeAddr>,
44 pub composite: CompositeType,
45}
46
47impl SubType {
48 #[inline]
49 pub const fn as_func(&self) -> Option<&FuncType> {
50 self.composite.as_func()
51 }
52
53 #[inline]
54 pub const fn as_struct(&self) -> Option<&StructType> {
55 self.composite.as_struct()
56 }
57
58 #[inline]
59 pub const fn as_array(&self) -> Option<&ArrayType> {
60 self.composite.as_array()
61 }
62}
63
64#[derive(Clone, PartialEq, Eq)]
68#[cfg_attr(feature = "debug", derive(Debug))]
69#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))]
70pub enum CompositeType {
71 Func(FuncType),
72 Struct(StructType),
73 Array(ArrayType),
74}
75
76impl CompositeType {
77 #[inline]
78 pub const fn as_func(&self) -> Option<&FuncType> {
79 match self {
80 Self::Func(ty) => Some(ty),
81 _ => None,
82 }
83 }
84
85 #[inline]
86 pub const fn as_struct(&self) -> Option<&StructType> {
87 match self {
88 Self::Struct(ty) => Some(ty),
89 _ => None,
90 }
91 }
92
93 #[inline]
94 pub const fn as_array(&self) -> Option<&ArrayType> {
95 match self {
96 Self::Array(ty) => Some(ty),
97 _ => None,
98 }
99 }
100}
101
102#[derive(Clone, PartialEq, Eq, Default)]
106#[cfg_attr(feature = "debug", derive(Debug))]
107#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))]
108pub struct FuncType {
109 data: Shared<[WasmType]>,
110 param_count: u16,
111}
112
113impl FuncType {
114 pub fn new(params: &[WasmType], results: &[WasmType]) -> Self {
116 let data: Box<[WasmType]> = params.iter().cloned().chain(results.iter().cloned()).collect();
117 Self { data: data.into(), param_count: params.len() as u16 }
118 }
119
120 pub fn params(&self) -> &[WasmType] {
122 &self.data[..self.param_count as usize]
123 }
124
125 pub fn results(&self) -> &[WasmType] {
127 &self.data[self.param_count as usize..]
128 }
129}
130
131#[derive(Clone, PartialEq, Eq, Default)]
135#[cfg_attr(feature = "debug", derive(Debug))]
136#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))]
137pub struct StructType {
138 pub fields: Box<[FieldType]>,
139}
140
141#[derive(Clone, PartialEq, Eq)]
145#[cfg_attr(feature = "debug", derive(Debug))]
146#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))]
147pub struct ArrayType {
148 pub field: FieldType,
149}
150
151#[derive(Clone, Copy, PartialEq, Eq)]
155#[cfg_attr(feature = "debug", derive(Debug))]
156#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))]
157pub struct FieldType {
158 pub storage: StorageType,
159 pub mutable: bool,
160}
161
162#[derive(Clone, Copy, PartialEq, Eq)]
166#[cfg_attr(feature = "debug", derive(Debug))]
167#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))]
168pub enum StorageType {
169 I8,
170 I16,
171 Value(WasmType),
172}
173
174impl StorageType {
175 pub const fn unpacked(self) -> WasmType {
177 match self {
178 Self::I8 | Self::I16 => WasmType::I32,
179 Self::Value(ty) => ty,
180 }
181 }
182}