1use crate::limits::*;
2use crate::{
3 BinaryReader, ComponentAlias, ComponentImport, ComponentTypeRef, FromReader, FuncType, Import,
4 Result, SectionLimited, Type, TypeRef,
5};
6
7#[derive(Clone, Copy, Debug, Eq, PartialEq)]
9pub enum OuterAliasKind {
10 Type,
12}
13
14#[derive(Debug, Clone)]
16pub enum CoreType<'a> {
17 Func(FuncType),
19 Module(Box<[ModuleTypeDeclaration<'a>]>),
21}
22
23impl<'a> FromReader<'a> for CoreType<'a> {
24 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
25 Ok(match reader.read_u8()? {
26 0x60 => CoreType::Func(reader.read()?),
27 0x50 => CoreType::Module(
28 reader
29 .read_iter(MAX_WASM_MODULE_TYPE_DECLS, "module type declaration")?
30 .collect::<Result<_>>()?,
31 ),
32 x => return reader.invalid_leading_byte(x, "core type"),
33 })
34 }
35}
36
37#[derive(Debug, Clone)]
39pub enum ModuleTypeDeclaration<'a> {
40 Type(Type),
42 Export {
44 name: &'a str,
46 ty: TypeRef,
48 },
49 OuterAlias {
51 kind: OuterAliasKind,
53 count: u32,
55 index: u32,
57 },
58 Import(Import<'a>),
60}
61
62impl<'a> FromReader<'a> for ModuleTypeDeclaration<'a> {
63 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
64 Ok(match reader.read_u8()? {
65 0x00 => ModuleTypeDeclaration::Import(reader.read()?),
66 0x01 => ModuleTypeDeclaration::Type(reader.read()?),
67 0x02 => {
68 let kind = match reader.read_u8()? {
69 0x10 => OuterAliasKind::Type,
70 x => {
71 return reader.invalid_leading_byte(x, "outer alias kind");
72 }
73 };
74 match reader.read_u8()? {
75 0x01 => ModuleTypeDeclaration::OuterAlias {
76 kind,
77 count: reader.read()?,
78 index: reader.read()?,
79 },
80 x => {
81 return reader.invalid_leading_byte(x, "outer alias target");
82 }
83 }
84 }
85 0x03 => ModuleTypeDeclaration::Export {
86 name: reader.read()?,
87 ty: reader.read()?,
88 },
89 x => return reader.invalid_leading_byte(x, "type definition"),
90 })
91 }
92}
93
94pub type CoreTypeSectionReader<'a> = SectionLimited<'a, CoreType<'a>>;
106
107#[derive(Debug, Clone, Copy, PartialEq, Eq)]
109pub enum ComponentValType {
110 Primitive(PrimitiveValType),
112 Type(u32),
114}
115
116impl<'a> FromReader<'a> for ComponentValType {
117 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
118 if let Some(ty) = PrimitiveValType::from_byte(reader.peek()?) {
119 reader.position += 1;
120 return Ok(ComponentValType::Primitive(ty));
121 }
122
123 Ok(ComponentValType::Type(reader.read_var_s33()? as u32))
124 }
125}
126
127impl<'a> FromReader<'a> for Option<ComponentValType> {
128 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
129 match reader.read_u8()? {
130 0x0 => Ok(None),
131 0x1 => Ok(Some(reader.read()?)),
132 x => reader.invalid_leading_byte(x, "optional component value type"),
133 }
134 }
135}
136
137#[derive(Debug, Clone, Copy, PartialEq, Eq)]
139pub enum PrimitiveValType {
140 Bool,
142 S8,
144 U8,
146 S16,
148 U16,
150 S32,
152 U32,
154 S64,
156 U64,
158 Float32,
160 Float64,
162 Char,
164 String,
166}
167
168impl PrimitiveValType {
169 fn from_byte(byte: u8) -> Option<PrimitiveValType> {
170 Some(match byte {
171 0x7f => PrimitiveValType::Bool,
172 0x7e => PrimitiveValType::S8,
173 0x7d => PrimitiveValType::U8,
174 0x7c => PrimitiveValType::S16,
175 0x7b => PrimitiveValType::U16,
176 0x7a => PrimitiveValType::S32,
177 0x79 => PrimitiveValType::U32,
178 0x78 => PrimitiveValType::S64,
179 0x77 => PrimitiveValType::U64,
180 0x76 => PrimitiveValType::Float32,
181 0x75 => PrimitiveValType::Float64,
182 0x74 => PrimitiveValType::Char,
183 0x73 => PrimitiveValType::String,
184 _ => return None,
185 })
186 }
187
188 pub(crate) fn requires_realloc(&self) -> bool {
189 matches!(self, Self::String)
190 }
191
192 pub fn is_subtype_of(a: Self, b: Self) -> bool {
194 a == b
201 }
202}
203
204#[derive(Debug, Clone)]
206pub enum ComponentType<'a> {
207 Defined(ComponentDefinedType<'a>),
209 Func(ComponentFuncType<'a>),
211 Component(Box<[ComponentTypeDeclaration<'a>]>),
213 Instance(Box<[InstanceTypeDeclaration<'a>]>),
215}
216
217impl<'a> FromReader<'a> for ComponentType<'a> {
218 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
219 Ok(match reader.read_u8()? {
220 0x40 => {
221 let params = reader
222 .read_iter(MAX_WASM_FUNCTION_PARAMS, "component function parameters")?
223 .collect::<Result<_>>()?;
224 let results = reader.read()?;
225 ComponentType::Func(ComponentFuncType { params, results })
226 }
227 0x41 => ComponentType::Component(
228 reader
229 .read_iter(MAX_WASM_COMPONENT_TYPE_DECLS, "component type declaration")?
230 .collect::<Result<_>>()?,
231 ),
232 0x42 => ComponentType::Instance(
233 reader
234 .read_iter(MAX_WASM_INSTANCE_TYPE_DECLS, "instance type declaration")?
235 .collect::<Result<_>>()?,
236 ),
237 x => {
238 if let Some(ty) = PrimitiveValType::from_byte(x) {
239 ComponentType::Defined(ComponentDefinedType::Primitive(ty))
240 } else {
241 ComponentType::Defined(ComponentDefinedType::read(reader, x)?)
242 }
243 }
244 })
245 }
246}
247
248#[derive(Debug, Clone)]
250pub enum ComponentTypeDeclaration<'a> {
251 CoreType(CoreType<'a>),
253 Type(ComponentType<'a>),
255 Alias(ComponentAlias<'a>),
257 Export {
259 name: &'a str,
261 url: &'a str,
263 ty: ComponentTypeRef,
265 },
266 Import(ComponentImport<'a>),
268}
269
270impl<'a> FromReader<'a> for ComponentTypeDeclaration<'a> {
271 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
272 if reader.peek()? == 0x03 {
276 reader.position += 1;
277 return Ok(ComponentTypeDeclaration::Import(reader.read()?));
278 }
279
280 Ok(match reader.read()? {
281 InstanceTypeDeclaration::CoreType(t) => ComponentTypeDeclaration::CoreType(t),
282 InstanceTypeDeclaration::Type(t) => ComponentTypeDeclaration::Type(t),
283 InstanceTypeDeclaration::Alias(a) => ComponentTypeDeclaration::Alias(a),
284 InstanceTypeDeclaration::Export { name, url, ty } => {
285 ComponentTypeDeclaration::Export { name, url, ty }
286 }
287 })
288 }
289}
290
291#[derive(Debug, Clone)]
293pub enum InstanceTypeDeclaration<'a> {
294 CoreType(CoreType<'a>),
296 Type(ComponentType<'a>),
298 Alias(ComponentAlias<'a>),
300 Export {
302 name: &'a str,
304 url: &'a str,
306 ty: ComponentTypeRef,
308 },
309}
310
311impl<'a> FromReader<'a> for InstanceTypeDeclaration<'a> {
312 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
313 Ok(match reader.read_u8()? {
314 0x00 => InstanceTypeDeclaration::CoreType(reader.read()?),
315 0x01 => InstanceTypeDeclaration::Type(reader.read()?),
316 0x02 => InstanceTypeDeclaration::Alias(reader.read()?),
317 0x04 => InstanceTypeDeclaration::Export {
318 name: reader.read()?,
319 url: reader.read()?,
320 ty: reader.read()?,
321 },
322 x => return reader.invalid_leading_byte(x, "component or instance type declaration"),
323 })
324 }
325}
326
327#[derive(Debug, Clone)]
329pub enum ComponentFuncResult<'a> {
330 Unnamed(ComponentValType),
332 Named(Box<[(&'a str, ComponentValType)]>),
334}
335
336impl<'a> FromReader<'a> for ComponentFuncResult<'a> {
337 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
338 Ok(match reader.read_u8()? {
339 0x00 => ComponentFuncResult::Unnamed(reader.read()?),
340 0x01 => ComponentFuncResult::Named(
341 reader
342 .read_iter(MAX_WASM_FUNCTION_RETURNS, "component function results")?
343 .collect::<Result<_>>()?,
344 ),
345 x => return reader.invalid_leading_byte(x, "component function results"),
346 })
347 }
348}
349
350impl ComponentFuncResult<'_> {
351 pub fn type_count(&self) -> usize {
353 match self {
354 Self::Unnamed(_) => 1,
355 Self::Named(vec) => vec.len(),
356 }
357 }
358
359 pub fn iter(&self) -> impl Iterator<Item = (Option<&str>, &ComponentValType)> {
361 enum Either<L, R> {
362 Left(L),
363 Right(R),
364 }
365
366 impl<L, R> Iterator for Either<L, R>
367 where
368 L: Iterator,
369 R: Iterator<Item = L::Item>,
370 {
371 type Item = L::Item;
372
373 fn next(&mut self) -> Option<Self::Item> {
374 match self {
375 Either::Left(l) => l.next(),
376 Either::Right(r) => r.next(),
377 }
378 }
379 }
380
381 match self {
382 Self::Unnamed(ty) => Either::Left(std::iter::once(ty).map(|ty| (None, ty))),
383 Self::Named(vec) => Either::Right(vec.iter().map(|(n, ty)| (Some(*n), ty))),
384 }
385 }
386}
387
388#[derive(Debug, Clone)]
390pub struct ComponentFuncType<'a> {
391 pub params: Box<[(&'a str, ComponentValType)]>,
393 pub results: ComponentFuncResult<'a>,
395}
396
397#[derive(Debug, Clone, PartialEq, Eq)]
399pub struct VariantCase<'a> {
400 pub name: &'a str,
402 pub ty: Option<ComponentValType>,
404 pub refines: Option<u32>,
406}
407
408impl<'a> FromReader<'a> for VariantCase<'a> {
409 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
410 Ok(VariantCase {
411 name: reader.read()?,
412 ty: reader.read()?,
413 refines: match reader.read_u8()? {
414 0x0 => None,
415 0x1 => Some(reader.read_var_u32()?),
416 x => return reader.invalid_leading_byte(x, "variant case refines"),
417 },
418 })
419 }
420}
421
422#[derive(Debug, Clone, PartialEq, Eq)]
424pub enum ComponentDefinedType<'a> {
425 Primitive(PrimitiveValType),
427 Record(Box<[(&'a str, ComponentValType)]>),
429 Variant(Box<[VariantCase<'a>]>),
431 List(ComponentValType),
433 Tuple(Box<[ComponentValType]>),
435 Flags(Box<[&'a str]>),
437 Enum(Box<[&'a str]>),
439 Union(Box<[ComponentValType]>),
441 Option(ComponentValType),
443 Result {
445 ok: Option<ComponentValType>,
447 err: Option<ComponentValType>,
449 },
450}
451
452impl<'a> ComponentDefinedType<'a> {
453 fn read(reader: &mut BinaryReader<'a>, byte: u8) -> Result<ComponentDefinedType<'a>> {
454 Ok(match byte {
455 0x72 => ComponentDefinedType::Record(
456 reader
457 .read_iter(MAX_WASM_RECORD_FIELDS, "record field")?
458 .collect::<Result<_>>()?,
459 ),
460 0x71 => ComponentDefinedType::Variant(
461 reader
462 .read_iter(MAX_WASM_VARIANT_CASES, "variant cases")?
463 .collect::<Result<_>>()?,
464 ),
465 0x70 => ComponentDefinedType::List(reader.read()?),
466 0x6f => ComponentDefinedType::Tuple(
467 reader
468 .read_iter(MAX_WASM_TUPLE_TYPES, "tuple types")?
469 .collect::<Result<_>>()?,
470 ),
471 0x6e => ComponentDefinedType::Flags(
472 reader
473 .read_iter(MAX_WASM_FLAG_NAMES, "flag names")?
474 .collect::<Result<_>>()?,
475 ),
476 0x6d => ComponentDefinedType::Enum(
477 reader
478 .read_iter(MAX_WASM_ENUM_CASES, "enum cases")?
479 .collect::<Result<_>>()?,
480 ),
481 0x6c => ComponentDefinedType::Union(
482 reader
483 .read_iter(MAX_WASM_UNION_TYPES, "union types")?
484 .collect::<Result<_>>()?,
485 ),
486 0x6b => ComponentDefinedType::Option(reader.read()?),
487 0x6a => ComponentDefinedType::Result {
488 ok: reader.read()?,
489 err: reader.read()?,
490 },
491 x => return reader.invalid_leading_byte(x, "component defined type"),
492 })
493 }
494}
495
496pub type ComponentTypeSectionReader<'a> = SectionLimited<'a, ComponentType<'a>>;