tinywasm_wasmparser/readers/component/
instances.rs

1use alloc::boxed::Box;
2
3use crate::limits::{MAX_WASM_INSTANTIATION_ARGS, MAX_WASM_INSTANTIATION_EXPORTS};
4use crate::{
5    BinaryReader, ComponentExport, ComponentExternalKind, Export, FromReader, Result,
6    SectionLimited,
7};
8
9/// Represents the kind of an instantiation argument for a core instance.
10#[derive(Debug, Copy, Clone, PartialEq, Eq)]
11pub enum InstantiationArgKind {
12    /// The instantiation argument is a core instance.
13    Instance,
14}
15
16/// Represents an argument to instantiating a WebAssembly module.
17#[derive(Debug, Clone)]
18pub struct InstantiationArg<'a> {
19    /// The name of the module argument.
20    pub name: &'a str,
21    /// The kind of the module argument.
22    pub kind: InstantiationArgKind,
23    /// The index of the argument item.
24    pub index: u32,
25}
26
27/// Represents an instance of a WebAssembly module.
28#[derive(Debug, Clone)]
29pub enum Instance<'a> {
30    /// The instance is from instantiating a WebAssembly module.
31    Instantiate {
32        /// The module index.
33        module_index: u32,
34        /// The module's instantiation arguments.
35        args: Box<[InstantiationArg<'a>]>,
36    },
37    /// The instance is a from exporting local items.
38    FromExports(Box<[Export<'a>]>),
39}
40
41/// A reader for the core instance section of a WebAssembly component.
42///
43/// # Examples
44///
45/// ```
46/// use tinywasm_wasmparser::InstanceSectionReader;
47/// # let data: &[u8] = &[0x01, 0x00, 0x00, 0x01, 0x03, b'f', b'o', b'o', 0x12, 0x00];
48/// let mut reader = InstanceSectionReader::new(data, 0).unwrap();
49/// for inst in reader {
50///     println!("Instance {:?}", inst.expect("instance"));
51/// }
52/// ```
53pub type InstanceSectionReader<'a> = SectionLimited<'a, Instance<'a>>;
54
55impl<'a> FromReader<'a> for Instance<'a> {
56    fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
57        Ok(match reader.read_u8()? {
58            0x00 => Instance::Instantiate {
59                module_index: reader.read_var_u32()?,
60                args: reader
61                    .read_iter(MAX_WASM_INSTANTIATION_ARGS, "core instantiation arguments")?
62                    .collect::<Result<_>>()?,
63            },
64            0x01 => Instance::FromExports(
65                reader
66                    .read_iter(MAX_WASM_INSTANTIATION_ARGS, "core instantiation arguments")?
67                    .collect::<Result<_>>()?,
68            ),
69            x => return reader.invalid_leading_byte(x, "core instance"),
70        })
71    }
72}
73
74impl<'a> FromReader<'a> for InstantiationArg<'a> {
75    fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
76        Ok(InstantiationArg {
77            name: reader.read()?,
78            kind: reader.read()?,
79            index: reader.read()?,
80        })
81    }
82}
83
84impl<'a> FromReader<'a> for InstantiationArgKind {
85    fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
86        Ok(match reader.read_u8()? {
87            0x12 => InstantiationArgKind::Instance,
88            x => return reader.invalid_leading_byte(x, "instantiation arg kind"),
89        })
90    }
91}
92
93/// Represents an argument to instantiating a WebAssembly component.
94#[derive(Debug, Clone)]
95pub struct ComponentInstantiationArg<'a> {
96    /// The name of the component argument.
97    pub name: &'a str,
98    /// The kind of the component argument.
99    pub kind: ComponentExternalKind,
100    /// The index of the argument item.
101    pub index: u32,
102}
103
104/// Represents an instance in a WebAssembly component.
105#[derive(Debug, Clone)]
106pub enum ComponentInstance<'a> {
107    /// The instance is from instantiating a WebAssembly component.
108    Instantiate {
109        /// The component index.
110        component_index: u32,
111        /// The component's instantiation arguments.
112        args: Box<[ComponentInstantiationArg<'a>]>,
113    },
114    /// The instance is a from exporting local items.
115    FromExports(Box<[ComponentExport<'a>]>),
116}
117
118/// A reader for the component instance section of a WebAssembly component.
119///
120/// # Examples
121///
122/// ```
123/// use tinywasm_wasmparser::ComponentInstanceSectionReader;
124/// # let data: &[u8] = &[0x01, 0x00, 0x00, 0x01, 0x03, b'f', b'o', b'o', 0x01, 0x00];
125/// let mut reader = ComponentInstanceSectionReader::new(data, 0).unwrap();
126/// for inst in reader {
127///     println!("Instance {:?}", inst.expect("instance"));
128/// }
129/// ```
130pub type ComponentInstanceSectionReader<'a> = SectionLimited<'a, ComponentInstance<'a>>;
131
132impl<'a> FromReader<'a> for ComponentInstance<'a> {
133    fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
134        Ok(match reader.read_u8()? {
135            0x00 => ComponentInstance::Instantiate {
136                component_index: reader.read_var_u32()?,
137                args: reader
138                    .read_iter(MAX_WASM_INSTANTIATION_ARGS, "instantiation arguments")?
139                    .collect::<Result<_>>()?,
140            },
141            0x01 => ComponentInstance::FromExports(
142                (0..reader.read_size(MAX_WASM_INSTANTIATION_EXPORTS, "instantiation exports")?)
143                    .map(|_| {
144                        Ok(ComponentExport {
145                            name: reader.read()?,
146                            kind: reader.read()?,
147                            index: reader.read()?,
148                            ty: None,
149                        })
150                    })
151                    .collect::<Result<_>>()?,
152            ),
153            x => return reader.invalid_leading_byte(x, "instance"),
154        })
155    }
156}
157impl<'a> FromReader<'a> for ComponentInstantiationArg<'a> {
158    fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
159        Ok(ComponentInstantiationArg {
160            name: reader.read()?,
161            kind: reader.read()?,
162            index: reader.read()?,
163        })
164    }
165}