wasm_encoder/component/
instances.rs

1use super::CORE_INSTANCE_SORT;
2use crate::{
3    encode_section, ComponentExportKind, ComponentSection, ComponentSectionId, Encode, ExportKind,
4};
5use alloc::vec::Vec;
6
7/// Represents an argument to a module instantiation.
8#[derive(Clone, Copy, Debug, Eq, PartialEq)]
9pub enum ModuleArg {
10    /// The argument is an instance.
11    Instance(u32),
12}
13
14impl Encode for ModuleArg {
15    fn encode(&self, sink: &mut Vec<u8>) {
16        let (sort, idx) = match self {
17            Self::Instance(idx) => (CORE_INSTANCE_SORT, *idx),
18        };
19        sink.push(sort);
20        idx.encode(sink);
21    }
22}
23
24/// An encoder for the core instance section of WebAssembly components.
25///
26/// # Example
27///
28/// ```rust
29/// use wasm_encoder::{Component, InstanceSection, ExportKind, ModuleArg};
30///
31/// let mut instances = InstanceSection::new();
32/// instances.export_items([("foo", ExportKind::Func, 0)]);
33/// instances.instantiate(1, [("foo", ModuleArg::Instance(0))]);
34///
35/// let mut component = Component::new();
36/// component.section(&instances);
37///
38/// let bytes = component.finish();
39/// ```
40#[derive(Clone, Debug, Default)]
41pub struct InstanceSection {
42    bytes: Vec<u8>,
43    num_added: u32,
44}
45
46impl InstanceSection {
47    /// Create a new core instance section encoder.
48    pub fn new() -> Self {
49        Self::default()
50    }
51
52    /// The number of instances in the section.
53    pub fn len(&self) -> u32 {
54        self.num_added
55    }
56
57    /// Determines if the section is empty.
58    pub fn is_empty(&self) -> bool {
59        self.num_added == 0
60    }
61
62    /// Define an instance by instantiating a core module.
63    pub fn instantiate<A, S>(&mut self, module_index: u32, args: A) -> &mut Self
64    where
65        A: IntoIterator<Item = (S, ModuleArg)>,
66        A::IntoIter: ExactSizeIterator,
67        S: AsRef<str>,
68    {
69        let args = args.into_iter();
70        self.bytes.push(0x00);
71        module_index.encode(&mut self.bytes);
72        args.len().encode(&mut self.bytes);
73        for (name, arg) in args {
74            name.as_ref().encode(&mut self.bytes);
75            arg.encode(&mut self.bytes);
76        }
77        self.num_added += 1;
78        self
79    }
80
81    /// Define an instance by exporting core WebAssembly items.
82    pub fn export_items<E, S>(&mut self, exports: E) -> &mut Self
83    where
84        E: IntoIterator<Item = (S, ExportKind, u32)>,
85        E::IntoIter: ExactSizeIterator,
86        S: AsRef<str>,
87    {
88        let exports = exports.into_iter();
89        self.bytes.push(0x01);
90        exports.len().encode(&mut self.bytes);
91        for (name, kind, index) in exports {
92            name.as_ref().encode(&mut self.bytes);
93            kind.encode(&mut self.bytes);
94            index.encode(&mut self.bytes);
95        }
96        self.num_added += 1;
97        self
98    }
99}
100
101impl Encode for InstanceSection {
102    fn encode(&self, sink: &mut Vec<u8>) {
103        encode_section(sink, self.num_added, &self.bytes);
104    }
105}
106
107impl ComponentSection for InstanceSection {
108    fn id(&self) -> u8 {
109        ComponentSectionId::CoreInstance.into()
110    }
111}
112
113/// An encoder for the instance section of WebAssembly components.
114///
115/// # Example
116///
117/// ```rust
118/// use wasm_encoder::{Component, ComponentInstanceSection, ComponentExportKind};
119///
120/// let mut instances = ComponentInstanceSection::new();
121/// instances.export_items([("foo", ComponentExportKind::Func, 0)]);
122/// instances.instantiate(1, [("foo", ComponentExportKind::Instance, 0)]);
123///
124/// let mut component = Component::new();
125/// component.section(&instances);
126///
127/// let bytes = component.finish();
128/// ```
129#[derive(Clone, Debug, Default)]
130pub struct ComponentInstanceSection {
131    bytes: Vec<u8>,
132    num_added: u32,
133}
134
135impl ComponentInstanceSection {
136    /// Create a new instance section encoder.
137    pub fn new() -> Self {
138        Self::default()
139    }
140
141    /// The number of instances in the section.
142    pub fn len(&self) -> u32 {
143        self.num_added
144    }
145
146    /// Determines if the section is empty.
147    pub fn is_empty(&self) -> bool {
148        self.num_added == 0
149    }
150
151    /// Define an instance by instantiating a component.
152    pub fn instantiate<A, S>(&mut self, component_index: u32, args: A) -> &mut Self
153    where
154        A: IntoIterator<Item = (S, ComponentExportKind, u32)>,
155        A::IntoIter: ExactSizeIterator,
156        S: AsRef<str>,
157    {
158        let args = args.into_iter();
159        self.bytes.push(0x00);
160        component_index.encode(&mut self.bytes);
161        args.len().encode(&mut self.bytes);
162        for (name, kind, index) in args {
163            name.as_ref().encode(&mut self.bytes);
164            kind.encode(&mut self.bytes);
165            index.encode(&mut self.bytes);
166        }
167        self.num_added += 1;
168        self
169    }
170
171    /// Define an instance by exporting items.
172    pub fn export_items<'a, E>(&mut self, exports: E) -> &mut Self
173    where
174        E: IntoIterator<Item = (&'a str, ComponentExportKind, u32)>,
175        E::IntoIter: ExactSizeIterator,
176    {
177        let exports = exports.into_iter();
178        self.bytes.push(0x01);
179        exports.len().encode(&mut self.bytes);
180        for (name, kind, index) in exports {
181            crate::encode_component_export_name(&mut self.bytes, name);
182            kind.encode(&mut self.bytes);
183            index.encode(&mut self.bytes);
184        }
185        self.num_added += 1;
186        self
187    }
188}
189
190impl Encode for ComponentInstanceSection {
191    fn encode(&self, sink: &mut Vec<u8>) {
192        encode_section(sink, self.num_added, &self.bytes);
193    }
194}
195
196impl ComponentSection for ComponentInstanceSection {
197    fn id(&self) -> u8 {
198        ComponentSectionId::Instance.into()
199    }
200}