wasmparser/readers/component/
instances.rs

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