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: readerBinaryReaderIter<'a, '_, …>
61 .read_iter(MAX_WASM_INSTANTIATION_ARGS, desc:"core instantiation arguments")?
62 .collect::<Result<_>>()?,
63 },
64 0x01 => Instance::FromExports(
65 readerBinaryReaderIter<'a, '_, …>
66 .read_iter(MAX_WASM_INSTANTIATION_ARGS, desc:"core instantiation arguments")?
67 .collect::<Result<_>>()?,
68 ),
69 x: u8 => return reader.invalid_leading_byte(byte:x, desc:"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: u8 => return reader.invalid_leading_byte(byte:x, desc:"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}
167