wasmparser/readers/component/
instances.rs

1use crate::limits::{MAX_WASM_INSTANTIATION_ARGS, MAX_WASM_INSTANTIATION_EXPORTS};
2use crate::prelude::*;
3use crate::{
4    BinaryReader, ComponentExport, ComponentExternalKind, Export, FromReader, Result,
5    SectionLimited,
6};
7
8/// Represents the kind of an instantiation argument for a core instance.
9#[derive(Debug, Copy, Clone, PartialEq, Eq)]
10pub enum InstantiationArgKind {
11    /// The instantiation argument is a core instance.
12    Instance,
13}
14
15/// Represents an argument to instantiating a WebAssembly module.
16#[derive(Debug, Clone, Eq, PartialEq)]
17pub struct InstantiationArg<'a> {
18    /// The name of the module argument.
19    pub name: &'a str,
20    /// The kind of the module argument.
21    pub kind: InstantiationArgKind,
22    /// The index of the argument item.
23    pub index: u32,
24}
25
26/// Represents an instance of a WebAssembly module.
27#[derive(Debug, Clone, Eq, PartialEq)]
28pub enum Instance<'a> {
29    /// The instance is from instantiating a WebAssembly module.
30    Instantiate {
31        /// The module index.
32        module_index: u32,
33        /// The module's instantiation arguments.
34        args: Box<[InstantiationArg<'a>]>,
35    },
36    /// The instance is a from exporting local items.
37    FromExports(Box<[Export<'a>]>),
38}
39
40/// A reader for the core instance section of a WebAssembly component.
41///
42/// # Examples
43///
44/// ```
45/// use wasmparser::{InstanceSectionReader, BinaryReader};
46/// # let data: &[u8] = &[0x01, 0x00, 0x00, 0x01, 0x03, b'f', b'o', b'o', 0x12, 0x00];
47/// let reader = BinaryReader::new(data, 0);
48/// let mut reader = InstanceSectionReader::new(reader).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, Eq, PartialEq)]
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, Eq, PartialEq)]
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 wasmparser::{ComponentInstanceSectionReader, BinaryReader};
124/// # let data: &[u8] = &[0x01, 0x00, 0x00, 0x01, 0x03, b'f', b'o', b'o', 0x01, 0x00];
125/// let reader = BinaryReader::new(data, 0);
126/// let mut reader = ComponentInstanceSectionReader::new(reader).unwrap();
127/// for inst in reader {
128///     println!("Instance {:?}", inst.expect("instance"));
129/// }
130/// ```
131pub type ComponentInstanceSectionReader<'a> = SectionLimited<'a, ComponentInstance<'a>>;
132
133impl<'a> FromReader<'a> for ComponentInstance<'a> {
134    fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
135        Ok(match reader.read_u8()? {
136            0x00 => ComponentInstance::Instantiate {
137                component_index: reader.read_var_u32()?,
138                args: reader
139                    .read_iter(MAX_WASM_INSTANTIATION_ARGS, "instantiation arguments")?
140                    .collect::<Result<_>>()?,
141            },
142            0x01 => ComponentInstance::FromExports(
143                (0..reader.read_size(MAX_WASM_INSTANTIATION_EXPORTS, "instantiation exports")?)
144                    .map(|_| {
145                        Ok(ComponentExport {
146                            name: reader.read()?,
147                            kind: reader.read()?,
148                            index: reader.read()?,
149                            ty: None,
150                        })
151                    })
152                    .collect::<Result<_>>()?,
153            ),
154            x => return reader.invalid_leading_byte(x, "instance"),
155        })
156    }
157}
158impl<'a> FromReader<'a> for ComponentInstantiationArg<'a> {
159    fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
160        Ok(ComponentInstantiationArg {
161            name: reader.read()?,
162            kind: reader.read()?,
163            index: reader.read()?,
164        })
165    }
166}