1use crate::limits::*;
2use crate::{
3 BinaryReader, ComponentAlias, ComponentImport, ComponentTypeRef, FromReader, FuncType, Import,
4 Result, SectionLimited, Type, TypeRef,
5};
6use ::alloc::boxed::Box;
7
8#[derive(Clone, Copy, Debug, Eq, PartialEq)]
10pub enum OuterAliasKind {
11 Type,
13}
14
15#[derive(Debug, Clone)]
17pub enum CoreType<'a> {
18 Func(FuncType),
20 Module(Box<[ModuleTypeDeclaration<'a>]>),
22}
23
24impl<'a> FromReader<'a> for CoreType<'a> {
25 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
26 Ok(match reader.read_u8()? {
27 0x60 => CoreType::Func(reader.read()?),
28 0x50 => CoreType::Module(
29 reader
30 .read_iter(MAX_WASM_MODULE_TYPE_DECLS, "module type declaration")?
31 .collect::<Result<_>>()?,
32 ),
33 x => return reader.invalid_leading_byte(x, "core type"),
34 })
35 }
36}
37
38#[derive(Debug, Clone)]
40pub enum ModuleTypeDeclaration<'a> {
41 Type(Type),
43 Export {
45 name: &'a str,
47 ty: TypeRef,
49 },
50 OuterAlias {
52 kind: OuterAliasKind,
54 count: u32,
56 index: u32,
58 },
59 Import(Import<'a>),
61}
62
63impl<'a> FromReader<'a> for ModuleTypeDeclaration<'a> {
64 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
65 Ok(match reader.read_u8()? {
66 0x00 => ModuleTypeDeclaration::Import(reader.read()?),
67 0x01 => ModuleTypeDeclaration::Type(reader.read()?),
68 0x02 => {
69 let kind = match reader.read_u8()? {
70 0x10 => OuterAliasKind::Type,
71 x => {
72 return reader.invalid_leading_byte(x, "outer alias kind");
73 }
74 };
75 match reader.read_u8()? {
76 0x01 => ModuleTypeDeclaration::OuterAlias {
77 kind,
78 count: reader.read()?,
79 index: reader.read()?,
80 },
81 x => {
82 return reader.invalid_leading_byte(x, "outer alias target");
83 }
84 }
85 }
86 0x03 => ModuleTypeDeclaration::Export {
87 name: reader.read()?,
88 ty: reader.read()?,
89 },
90 x => return reader.invalid_leading_byte(x, "type definition"),
91 })
92 }
93}
94
95pub type CoreTypeSectionReader<'a> = SectionLimited<'a, CoreType<'a>>;
107
108#[derive(Debug, Clone, Copy, PartialEq, Eq)]
110pub enum ComponentValType {
111 Primitive(PrimitiveValType),
113 Type(u32),
115}
116
117impl<'a> FromReader<'a> for ComponentValType {
118 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
119 if let Some(ty) = PrimitiveValType::from_byte(reader.peek()?) {
120 reader.position += 1;
121 return Ok(ComponentValType::Primitive(ty));
122 }
123
124 Ok(ComponentValType::Type(reader.read_var_s33()? as u32))
125 }
126}
127
128impl<'a> FromReader<'a> for Option<ComponentValType> {
129 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
130 match reader.read_u8()? {
131 0x0 => Ok(None),
132 0x1 => Ok(Some(reader.read()?)),
133 x => reader.invalid_leading_byte(x, "optional component value type"),
134 }
135 }
136}
137
138#[derive(Debug, Clone, Copy, PartialEq, Eq)]
140pub enum PrimitiveValType {
141 Bool,
143 S8,
145 U8,
147 S16,
149 U16,
151 S32,
153 U32,
155 S64,
157 U64,
159 Float32,
161 Float64,
163 Char,
165 String,
167}
168
169impl PrimitiveValType {
170 fn from_byte(byte: u8) -> Option<PrimitiveValType> {
171 Some(match byte {
172 0x7f => PrimitiveValType::Bool,
173 0x7e => PrimitiveValType::S8,
174 0x7d => PrimitiveValType::U8,
175 0x7c => PrimitiveValType::S16,
176 0x7b => PrimitiveValType::U16,
177 0x7a => PrimitiveValType::S32,
178 0x79 => PrimitiveValType::U32,
179 0x78 => PrimitiveValType::S64,
180 0x77 => PrimitiveValType::U64,
181 0x76 => PrimitiveValType::Float32,
182 0x75 => PrimitiveValType::Float64,
183 0x74 => PrimitiveValType::Char,
184 0x73 => PrimitiveValType::String,
185 _ => return None,
186 })
187 }
188
189 pub(crate) fn requires_realloc(&self) -> bool {
190 matches!(self, Self::String)
191 }
192
193 pub fn is_subtype_of(a: Self, b: Self) -> bool {
195 a == b
202 }
203}
204
205#[derive(Debug, Clone)]
207pub enum ComponentType<'a> {
208 Defined(ComponentDefinedType<'a>),
210 Func(ComponentFuncType<'a>),
212 Component(Box<[ComponentTypeDeclaration<'a>]>),
214 Instance(Box<[InstanceTypeDeclaration<'a>]>),
216}
217
218impl<'a> FromReader<'a> for ComponentType<'a> {
219 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
220 Ok(match reader.read_u8()? {
221 0x40 => {
222 let params = reader
223 .read_iter(MAX_WASM_FUNCTION_PARAMS, "component function parameters")?
224 .collect::<Result<_>>()?;
225 let results = reader.read()?;
226 ComponentType::Func(ComponentFuncType { params, results })
227 }
228 0x41 => ComponentType::Component(
229 reader
230 .read_iter(MAX_WASM_COMPONENT_TYPE_DECLS, "component type declaration")?
231 .collect::<Result<_>>()?,
232 ),
233 0x42 => ComponentType::Instance(
234 reader
235 .read_iter(MAX_WASM_INSTANCE_TYPE_DECLS, "instance type declaration")?
236 .collect::<Result<_>>()?,
237 ),
238 x => {
239 if let Some(ty) = PrimitiveValType::from_byte(x) {
240 ComponentType::Defined(ComponentDefinedType::Primitive(ty))
241 } else {
242 ComponentType::Defined(ComponentDefinedType::read(reader, x)?)
243 }
244 }
245 })
246 }
247}
248
249#[derive(Debug, Clone)]
251pub enum ComponentTypeDeclaration<'a> {
252 CoreType(CoreType<'a>),
254 Type(ComponentType<'a>),
256 Alias(ComponentAlias<'a>),
258 Export {
260 name: &'a str,
262 url: &'a str,
264 ty: ComponentTypeRef,
266 },
267 Import(ComponentImport<'a>),
269}
270
271impl<'a> FromReader<'a> for ComponentTypeDeclaration<'a> {
272 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
273 if reader.peek()? == 0x03 {
277 reader.position += 1;
278 return Ok(ComponentTypeDeclaration::Import(reader.read()?));
279 }
280
281 Ok(match reader.read()? {
282 InstanceTypeDeclaration::CoreType(t) => ComponentTypeDeclaration::CoreType(t),
283 InstanceTypeDeclaration::Type(t) => ComponentTypeDeclaration::Type(t),
284 InstanceTypeDeclaration::Alias(a) => ComponentTypeDeclaration::Alias(a),
285 InstanceTypeDeclaration::Export { name, url, ty } => {
286 ComponentTypeDeclaration::Export { name, url, ty }
287 }
288 })
289 }
290}
291
292#[derive(Debug, Clone)]
294pub enum InstanceTypeDeclaration<'a> {
295 CoreType(CoreType<'a>),
297 Type(ComponentType<'a>),
299 Alias(ComponentAlias<'a>),
301 Export {
303 name: &'a str,
305 url: &'a str,
307 ty: ComponentTypeRef,
309 },
310}
311
312impl<'a> FromReader<'a> for InstanceTypeDeclaration<'a> {
313 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
314 Ok(match reader.read_u8()? {
315 0x00 => InstanceTypeDeclaration::CoreType(reader.read()?),
316 0x01 => InstanceTypeDeclaration::Type(reader.read()?),
317 0x02 => InstanceTypeDeclaration::Alias(reader.read()?),
318 0x04 => InstanceTypeDeclaration::Export {
319 name: reader.read()?,
320 url: reader.read()?,
321 ty: reader.read()?,
322 },
323 x => return reader.invalid_leading_byte(x, "component or instance type declaration"),
324 })
325 }
326}
327
328#[derive(Debug, Clone)]
330pub enum ComponentFuncResult<'a> {
331 Unnamed(ComponentValType),
333 Named(Box<[(&'a str, ComponentValType)]>),
335}
336
337impl<'a> FromReader<'a> for ComponentFuncResult<'a> {
338 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
339 Ok(match reader.read_u8()? {
340 0x00 => ComponentFuncResult::Unnamed(reader.read()?),
341 0x01 => ComponentFuncResult::Named(
342 reader
343 .read_iter(MAX_WASM_FUNCTION_RETURNS, "component function results")?
344 .collect::<Result<_>>()?,
345 ),
346 x => return reader.invalid_leading_byte(x, "component function results"),
347 })
348 }
349}
350
351impl ComponentFuncResult<'_> {
352 pub fn type_count(&self) -> usize {
354 match self {
355 Self::Unnamed(_) => 1,
356 Self::Named(vec) => vec.len(),
357 }
358 }
359
360 pub fn iter(&self) -> impl Iterator<Item = (Option<&str>, &ComponentValType)> {
362 enum Either<L, R> {
363 Left(L),
364 Right(R),
365 }
366
367 impl<L, R> Iterator for Either<L, R>
368 where
369 L: Iterator,
370 R: Iterator<Item = L::Item>,
371 {
372 type Item = L::Item;
373
374 fn next(&mut self) -> Option<Self::Item> {
375 match self {
376 Either::Left(l) => l.next(),
377 Either::Right(r) => r.next(),
378 }
379 }
380 }
381
382 match self {
383 Self::Unnamed(ty) => Either::Left(::core::iter::once(ty).map(|ty| (None, ty))),
384 Self::Named(vec) => Either::Right(vec.iter().map(|(n, ty)| (Some(*n), ty))),
385 }
386 }
387}
388
389#[derive(Debug, Clone)]
391pub struct ComponentFuncType<'a> {
392 pub params: Box<[(&'a str, ComponentValType)]>,
394 pub results: ComponentFuncResult<'a>,
396}
397
398#[derive(Debug, Clone, PartialEq, Eq)]
400pub struct VariantCase<'a> {
401 pub name: &'a str,
403 pub ty: Option<ComponentValType>,
405 pub refines: Option<u32>,
407}
408
409impl<'a> FromReader<'a> for VariantCase<'a> {
410 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
411 Ok(VariantCase {
412 name: reader.read()?,
413 ty: reader.read()?,
414 refines: match reader.read_u8()? {
415 0x0 => None,
416 0x1 => Some(reader.read_var_u32()?),
417 x => return reader.invalid_leading_byte(x, "variant case refines"),
418 },
419 })
420 }
421}
422
423#[derive(Debug, Clone, PartialEq, Eq)]
425pub enum ComponentDefinedType<'a> {
426 Primitive(PrimitiveValType),
428 Record(Box<[(&'a str, ComponentValType)]>),
430 Variant(Box<[VariantCase<'a>]>),
432 List(ComponentValType),
434 Tuple(Box<[ComponentValType]>),
436 Flags(Box<[&'a str]>),
438 Enum(Box<[&'a str]>),
440 Union(Box<[ComponentValType]>),
442 Option(ComponentValType),
444 Result {
446 ok: Option<ComponentValType>,
448 err: Option<ComponentValType>,
450 },
451}
452
453impl<'a> ComponentDefinedType<'a> {
454 fn read(reader: &mut BinaryReader<'a>, byte: u8) -> Result<ComponentDefinedType<'a>> {
455 Ok(match byte {
456 0x72 => ComponentDefinedType::Record(
457 reader
458 .read_iter(MAX_WASM_RECORD_FIELDS, "record field")?
459 .collect::<Result<_>>()?,
460 ),
461 0x71 => ComponentDefinedType::Variant(
462 reader
463 .read_iter(MAX_WASM_VARIANT_CASES, "variant cases")?
464 .collect::<Result<_>>()?,
465 ),
466 0x70 => ComponentDefinedType::List(reader.read()?),
467 0x6f => ComponentDefinedType::Tuple(
468 reader
469 .read_iter(MAX_WASM_TUPLE_TYPES, "tuple types")?
470 .collect::<Result<_>>()?,
471 ),
472 0x6e => ComponentDefinedType::Flags(
473 reader
474 .read_iter(MAX_WASM_FLAG_NAMES, "flag names")?
475 .collect::<Result<_>>()?,
476 ),
477 0x6d => ComponentDefinedType::Enum(
478 reader
479 .read_iter(MAX_WASM_ENUM_CASES, "enum cases")?
480 .collect::<Result<_>>()?,
481 ),
482 0x6c => ComponentDefinedType::Union(
483 reader
484 .read_iter(MAX_WASM_UNION_TYPES, "union types")?
485 .collect::<Result<_>>()?,
486 ),
487 0x6b => ComponentDefinedType::Option(reader.read()?),
488 0x6a => ComponentDefinedType::Result {
489 ok: reader.read()?,
490 err: reader.read()?,
491 },
492 x => return reader.invalid_leading_byte(x, "component defined type"),
493 })
494 }
495}
496
497pub type ComponentTypeSectionReader<'a> = SectionLimited<'a, ComponentType<'a>>;