wasm_encoder/component/
builder.rs

1use crate::component::*;
2use crate::{ExportKind, Module, RawSection, ValType};
3use alloc::vec::Vec;
4use core::mem;
5
6/// Convenience type to build a component incrementally and automatically keep
7/// track of index spaces.
8///
9/// This type is intended to be a wrapper around the [`Component`] encoding type
10/// which is useful for building it up incrementally over time. This type will
11/// automatically collect definitions into sections and reports the index of all
12/// items added by keeping track of indices internally.
13#[derive(Debug, Default)]
14pub struct ComponentBuilder {
15    /// The binary component that's being built.
16    component: Component,
17
18    /// The last section which was appended to during encoding. This type is
19    /// generated by the `section_accessors` macro below.
20    ///
21    /// When something is encoded this is used if it matches the kind of item
22    /// being encoded, otherwise it's "flushed" to the output component and a
23    /// new section is started.
24    last_section: LastSection,
25
26    // Core index spaces
27    core_modules: u32,
28    core_funcs: u32,
29    core_types: u32,
30    core_memories: u32,
31    core_tables: u32,
32    core_instances: u32,
33    core_tags: u32,
34    core_globals: u32,
35
36    // Component index spaces
37    funcs: u32,
38    instances: u32,
39    types: u32,
40    components: u32,
41    values: u32,
42}
43
44impl ComponentBuilder {
45    /// Returns the current number of core modules.
46    pub fn core_module_count(&self) -> u32 {
47        self.core_modules
48    }
49
50    /// Returns the current number of core funcs.
51    pub fn core_func_count(&self) -> u32 {
52        self.core_funcs
53    }
54
55    /// Returns the current number of core types.
56    pub fn core_type_count(&self) -> u32 {
57        self.core_types
58    }
59
60    /// Returns the current number of core memories.
61    pub fn core_memory_count(&self) -> u32 {
62        self.core_memories
63    }
64
65    /// Returns the current number of core tables.
66    pub fn core_table_count(&self) -> u32 {
67        self.core_tables
68    }
69
70    /// Returns the current number of core instances.
71    pub fn core_instance_count(&self) -> u32 {
72        self.core_instances
73    }
74
75    /// Returns the current number of core tags.
76    pub fn core_tag_count(&self) -> u32 {
77        self.core_tags
78    }
79
80    /// Returns the current number of core globals.
81    pub fn core_global_count(&self) -> u32 {
82        self.core_globals
83    }
84
85    /// Returns the current number of component funcs.
86    pub fn func_count(&self) -> u32 {
87        self.funcs
88    }
89
90    /// Returns the current number of component instances.
91    pub fn instance_count(&self) -> u32 {
92        self.instances
93    }
94
95    /// Returns the current number of component values.
96    pub fn value_count(&self) -> u32 {
97        self.values
98    }
99
100    /// Returns the current number of components.
101    pub fn component_count(&self) -> u32 {
102        self.components
103    }
104
105    /// Returns the current number of component types.
106    pub fn type_count(&self) -> u32 {
107        self.types
108    }
109
110    /// Completes this component and returns the binary encoding of the entire
111    /// component.
112    pub fn finish(mut self) -> Vec<u8> {
113        self.flush();
114        self.component.finish()
115    }
116
117    /// Encodes a core wasm `Module` into this component, returning its index.
118    pub fn core_module(&mut self, module: &Module) -> u32 {
119        self.flush();
120        self.component.section(&ModuleSection(module));
121        inc(&mut self.core_modules)
122    }
123
124    /// Encodes a core wasm `module` into this component, returning its index.
125    pub fn core_module_raw(&mut self, module: &[u8]) -> u32 {
126        self.flush();
127        self.component.section(&RawSection {
128            id: ComponentSectionId::CoreModule.into(),
129            data: module,
130        });
131        inc(&mut self.core_modules)
132    }
133
134    /// Instantiates a core wasm module at `module_index` with the `args`
135    /// provided.
136    ///
137    /// Returns the index of the core wasm instance created.
138    pub fn core_instantiate<'a, A>(&mut self, module_index: u32, args: A) -> u32
139    where
140        A: IntoIterator<Item = (&'a str, ModuleArg)>,
141        A::IntoIter: ExactSizeIterator,
142    {
143        self.instances().instantiate(module_index, args);
144        inc(&mut self.core_instances)
145    }
146
147    /// Creates a new core wasm instance from the `exports` provided.
148    ///
149    /// Returns the index of the core wasm instance created.
150    pub fn core_instantiate_exports<'a, E>(&mut self, exports: E) -> u32
151    where
152        E: IntoIterator<Item = (&'a str, ExportKind, u32)>,
153        E::IntoIter: ExactSizeIterator,
154    {
155        self.instances().export_items(exports);
156        inc(&mut self.core_instances)
157    }
158
159    /// Creates a new aliased item where the core `instance` specified has its
160    /// export `name` aliased out with the `kind` specified.
161    ///
162    /// Returns the index of the item created.
163    pub fn core_alias_export(&mut self, instance: u32, name: &str, kind: ExportKind) -> u32 {
164        self.alias(Alias::CoreInstanceExport {
165            instance,
166            kind,
167            name,
168        })
169    }
170
171    /// Adds a new alias to this component
172    pub fn alias(&mut self, alias: Alias<'_>) -> u32 {
173        self.aliases().alias(alias);
174        match alias {
175            Alias::InstanceExport { kind, .. } => self.inc_kind(kind),
176            Alias::CoreInstanceExport { kind, .. } => self.inc_core_kind(kind),
177            Alias::Outer {
178                kind: ComponentOuterAliasKind::Type,
179                ..
180            } => inc(&mut self.types),
181            Alias::Outer {
182                kind: ComponentOuterAliasKind::CoreModule,
183                ..
184            } => inc(&mut self.core_modules),
185            Alias::Outer {
186                kind: ComponentOuterAliasKind::Component,
187                ..
188            } => inc(&mut self.components),
189            Alias::Outer {
190                kind: ComponentOuterAliasKind::CoreType,
191                ..
192            } => inc(&mut self.core_types),
193        }
194    }
195
196    /// Creates an alias to a previous component instance's exported item.
197    ///
198    /// The `instance` provided is the instance to access and the `name` is the
199    /// item to access.
200    ///
201    /// Returns the index of the new item defined.
202    pub fn alias_export(&mut self, instance: u32, name: &str, kind: ComponentExportKind) -> u32 {
203        self.alias(Alias::InstanceExport {
204            instance,
205            kind,
206            name,
207        })
208    }
209
210    fn inc_kind(&mut self, kind: ComponentExportKind) -> u32 {
211        match kind {
212            ComponentExportKind::Func => inc(&mut self.funcs),
213            ComponentExportKind::Module => inc(&mut self.core_modules),
214            ComponentExportKind::Type => inc(&mut self.types),
215            ComponentExportKind::Component => inc(&mut self.components),
216            ComponentExportKind::Instance => inc(&mut self.instances),
217            ComponentExportKind::Value => inc(&mut self.values),
218        }
219    }
220
221    fn inc_core_kind(&mut self, kind: ExportKind) -> u32 {
222        match kind {
223            ExportKind::Func => inc(&mut self.core_funcs),
224            ExportKind::Table => inc(&mut self.core_tables),
225            ExportKind::Memory => inc(&mut self.core_memories),
226            ExportKind::Global => inc(&mut self.core_globals),
227            ExportKind::Tag => inc(&mut self.core_tags),
228        }
229    }
230
231    /// Lowers the `func_index` component function into a core wasm function
232    /// using the `options` provided.
233    ///
234    /// Returns the index of the core wasm function created.
235    pub fn lower_func<O>(&mut self, func_index: u32, options: O) -> u32
236    where
237        O: IntoIterator<Item = CanonicalOption>,
238        O::IntoIter: ExactSizeIterator,
239    {
240        self.canonical_functions().lower(func_index, options);
241        inc(&mut self.core_funcs)
242    }
243
244    /// Lifts the core wasm `core_func_index` function with the component
245    /// function type `type_index` and `options`.
246    ///
247    /// Returns the index of the component function created.
248    pub fn lift_func<O>(&mut self, core_func_index: u32, type_index: u32, options: O) -> u32
249    where
250        O: IntoIterator<Item = CanonicalOption>,
251        O::IntoIter: ExactSizeIterator,
252    {
253        self.canonical_functions()
254            .lift(core_func_index, type_index, options);
255        inc(&mut self.funcs)
256    }
257
258    /// Imports a new item into this component with the `name` and `ty` specified.
259    pub fn import(&mut self, name: &str, ty: ComponentTypeRef) -> u32 {
260        let ret = match &ty {
261            ComponentTypeRef::Instance(_) => inc(&mut self.instances),
262            ComponentTypeRef::Func(_) => inc(&mut self.funcs),
263            ComponentTypeRef::Type(..) => inc(&mut self.types),
264            ComponentTypeRef::Component(_) => inc(&mut self.components),
265            ComponentTypeRef::Module(_) => inc(&mut self.core_modules),
266            ComponentTypeRef::Value(_) => inc(&mut self.values),
267        };
268        self.imports().import(name, ty);
269        ret
270    }
271
272    /// Exports a new item from this component with the `name` and `kind`
273    /// specified.
274    ///
275    /// The `idx` is the item to export and the `ty` is an optional type to
276    /// ascribe to the export.
277    pub fn export(
278        &mut self,
279        name: &str,
280        kind: ComponentExportKind,
281        idx: u32,
282        ty: Option<ComponentTypeRef>,
283    ) -> u32 {
284        self.exports().export(name, kind, idx, ty);
285        self.inc_kind(kind)
286    }
287
288    /// Creates a new encoder for the next core type in this component.
289    pub fn core_type(&mut self) -> (u32, ComponentCoreTypeEncoder<'_>) {
290        (inc(&mut self.core_types), self.core_types().ty())
291    }
292
293    /// Creates a new encoder for the next type in this component.
294    pub fn ty(&mut self) -> (u32, ComponentTypeEncoder<'_>) {
295        (inc(&mut self.types), self.types().ty())
296    }
297
298    /// Creates a new instance type within this component.
299    pub fn type_instance(&mut self, ty: &InstanceType) -> u32 {
300        self.types().instance(ty);
301        inc(&mut self.types)
302    }
303
304    /// Creates a new component type within this component.
305    pub fn type_component(&mut self, ty: &ComponentType) -> u32 {
306        self.types().component(ty);
307        inc(&mut self.types)
308    }
309
310    /// Creates a new defined component type within this component.
311    pub fn type_defined(&mut self) -> (u32, ComponentDefinedTypeEncoder<'_>) {
312        (inc(&mut self.types), self.types().defined_type())
313    }
314
315    /// Creates a new component function type within this component.
316    pub fn type_function(&mut self) -> (u32, ComponentFuncTypeEncoder<'_>) {
317        (inc(&mut self.types), self.types().function())
318    }
319
320    /// Declares a new resource type within this component.
321    pub fn type_resource(&mut self, rep: ValType, dtor: Option<u32>) -> u32 {
322        self.types().resource(rep, dtor);
323        inc(&mut self.types)
324    }
325
326    /// Defines a new subcomponent of this component.
327    pub fn component(&mut self, mut builder: ComponentBuilder) -> u32 {
328        builder.flush();
329        self.flush();
330        self.component
331            .section(&NestedComponentSection(&builder.component));
332        inc(&mut self.components)
333    }
334
335    /// Defines a new subcomponent of this component.
336    pub fn component_raw(&mut self, data: &[u8]) -> u32 {
337        let raw_section = RawSection {
338            id: ComponentSectionId::Component.into(),
339            data,
340        };
341        self.flush();
342        self.component.section(&raw_section);
343        inc(&mut self.components)
344    }
345
346    /// Instantiates the `component_index` specified with the `args` specified.
347    pub fn instantiate<A, S>(&mut self, component_index: u32, args: A) -> u32
348    where
349        A: IntoIterator<Item = (S, ComponentExportKind, u32)>,
350        A::IntoIter: ExactSizeIterator,
351        S: AsRef<str>,
352    {
353        self.component_instances()
354            .instantiate(component_index, args);
355        inc(&mut self.instances)
356    }
357
358    /// Declares a new `resource.drop` intrinsic.
359    pub fn resource_drop(&mut self, ty: u32) -> u32 {
360        self.canonical_functions().resource_drop(ty);
361        inc(&mut self.core_funcs)
362    }
363
364    /// Declares a new `resource.drop` intrinsic.
365    pub fn resource_drop_async(&mut self, ty: u32) -> u32 {
366        self.canonical_functions().resource_drop_async(ty);
367        inc(&mut self.core_funcs)
368    }
369
370    /// Declares a new `resource.new` intrinsic.
371    pub fn resource_new(&mut self, ty: u32) -> u32 {
372        self.canonical_functions().resource_new(ty);
373        inc(&mut self.core_funcs)
374    }
375
376    /// Declares a new `resource.rep` intrinsic.
377    pub fn resource_rep(&mut self, ty: u32) -> u32 {
378        self.canonical_functions().resource_rep(ty);
379        inc(&mut self.core_funcs)
380    }
381
382    /// Declares a new `thread.spawn_ref` intrinsic.
383    pub fn thread_spawn_ref(&mut self, ty: u32) -> u32 {
384        self.canonical_functions().thread_spawn_ref(ty);
385        inc(&mut self.core_funcs)
386    }
387
388    /// Declares a new `thread.available_parallelism` intrinsic.
389    pub fn thread_available_parallelism(&mut self) -> u32 {
390        self.canonical_functions().thread_available_parallelism();
391        inc(&mut self.core_funcs)
392    }
393
394    /// Declares a new `backpressure.set` intrinsic.
395    pub fn backpressure_set(&mut self) -> u32 {
396        self.canonical_functions().backpressure_set();
397        inc(&mut self.core_funcs)
398    }
399
400    /// Declares a new `backpressure.inc` intrinsic.
401    pub fn backpressure_inc(&mut self) -> u32 {
402        self.canonical_functions().backpressure_inc();
403        inc(&mut self.core_funcs)
404    }
405
406    /// Declares a new `backpressure.dec` intrinsic.
407    pub fn backpressure_dec(&mut self) -> u32 {
408        self.canonical_functions().backpressure_dec();
409        inc(&mut self.core_funcs)
410    }
411
412    /// Declares a new `task.return` intrinsic.
413    pub fn task_return<O>(&mut self, ty: Option<ComponentValType>, options: O) -> u32
414    where
415        O: IntoIterator<Item = CanonicalOption>,
416        O::IntoIter: ExactSizeIterator,
417    {
418        self.canonical_functions().task_return(ty, options);
419        inc(&mut self.core_funcs)
420    }
421
422    /// Declares a new `task.cancel` intrinsic.
423    pub fn task_cancel(&mut self) -> u32 {
424        self.canonical_functions().task_cancel();
425        inc(&mut self.core_funcs)
426    }
427
428    /// Declares a new `context.get` intrinsic.
429    pub fn context_get(&mut self, i: u32) -> u32 {
430        self.canonical_functions().context_get(i);
431        inc(&mut self.core_funcs)
432    }
433
434    /// Declares a new `context.set` intrinsic.
435    pub fn context_set(&mut self, i: u32) -> u32 {
436        self.canonical_functions().context_set(i);
437        inc(&mut self.core_funcs)
438    }
439
440    /// Declares a new `thread.yield` intrinsic.
441    pub fn thread_yield(&mut self, cancellable: bool) -> u32 {
442        self.canonical_functions().thread_yield(cancellable);
443        inc(&mut self.core_funcs)
444    }
445
446    /// Declares a new `subtask.drop` intrinsic.
447    pub fn subtask_drop(&mut self) -> u32 {
448        self.canonical_functions().subtask_drop();
449        inc(&mut self.core_funcs)
450    }
451
452    /// Declares a new `subtask.cancel` intrinsic.
453    pub fn subtask_cancel(&mut self, async_: bool) -> u32 {
454        self.canonical_functions().subtask_cancel(async_);
455        inc(&mut self.core_funcs)
456    }
457
458    /// Declares a new `stream.new` intrinsic.
459    pub fn stream_new(&mut self, ty: u32) -> u32 {
460        self.canonical_functions().stream_new(ty);
461        inc(&mut self.core_funcs)
462    }
463
464    /// Declares a new `stream.read` intrinsic.
465    pub fn stream_read<O>(&mut self, ty: u32, options: O) -> u32
466    where
467        O: IntoIterator<Item = CanonicalOption>,
468        O::IntoIter: ExactSizeIterator,
469    {
470        self.canonical_functions().stream_read(ty, options);
471        inc(&mut self.core_funcs)
472    }
473
474    /// Declares a new `stream.write` intrinsic.
475    pub fn stream_write<O>(&mut self, ty: u32, options: O) -> u32
476    where
477        O: IntoIterator<Item = CanonicalOption>,
478        O::IntoIter: ExactSizeIterator,
479    {
480        self.canonical_functions().stream_write(ty, options);
481        inc(&mut self.core_funcs)
482    }
483
484    /// Declares a new `stream.cancel-read` intrinsic.
485    pub fn stream_cancel_read(&mut self, ty: u32, async_: bool) -> u32 {
486        self.canonical_functions().stream_cancel_read(ty, async_);
487        inc(&mut self.core_funcs)
488    }
489
490    /// Declares a new `stream.cancel-write` intrinsic.
491    pub fn stream_cancel_write(&mut self, ty: u32, async_: bool) -> u32 {
492        self.canonical_functions().stream_cancel_write(ty, async_);
493        inc(&mut self.core_funcs)
494    }
495
496    /// Declares a new `stream.drop-readable` intrinsic.
497    pub fn stream_drop_readable(&mut self, ty: u32) -> u32 {
498        self.canonical_functions().stream_drop_readable(ty);
499        inc(&mut self.core_funcs)
500    }
501
502    /// Declares a new `stream.drop-writable` intrinsic.
503    pub fn stream_drop_writable(&mut self, ty: u32) -> u32 {
504        self.canonical_functions().stream_drop_writable(ty);
505        inc(&mut self.core_funcs)
506    }
507
508    /// Declares a new `future.new` intrinsic.
509    pub fn future_new(&mut self, ty: u32) -> u32 {
510        self.canonical_functions().future_new(ty);
511        inc(&mut self.core_funcs)
512    }
513
514    /// Declares a new `future.read` intrinsic.
515    pub fn future_read<O>(&mut self, ty: u32, options: O) -> u32
516    where
517        O: IntoIterator<Item = CanonicalOption>,
518        O::IntoIter: ExactSizeIterator,
519    {
520        self.canonical_functions().future_read(ty, options);
521        inc(&mut self.core_funcs)
522    }
523
524    /// Declares a new `future.write` intrinsic.
525    pub fn future_write<O>(&mut self, ty: u32, options: O) -> u32
526    where
527        O: IntoIterator<Item = CanonicalOption>,
528        O::IntoIter: ExactSizeIterator,
529    {
530        self.canonical_functions().future_write(ty, options);
531        inc(&mut self.core_funcs)
532    }
533
534    /// Declares a new `future.cancel-read` intrinsic.
535    pub fn future_cancel_read(&mut self, ty: u32, async_: bool) -> u32 {
536        self.canonical_functions().future_cancel_read(ty, async_);
537        inc(&mut self.core_funcs)
538    }
539
540    /// Declares a new `future.cancel-write` intrinsic.
541    pub fn future_cancel_write(&mut self, ty: u32, async_: bool) -> u32 {
542        self.canonical_functions().future_cancel_write(ty, async_);
543        inc(&mut self.core_funcs)
544    }
545
546    /// Declares a new `future.drop-readable` intrinsic.
547    pub fn future_drop_readable(&mut self, ty: u32) -> u32 {
548        self.canonical_functions().future_drop_readable(ty);
549        inc(&mut self.core_funcs)
550    }
551
552    /// Declares a new `future.drop-writable` intrinsic.
553    pub fn future_drop_writable(&mut self, ty: u32) -> u32 {
554        self.canonical_functions().future_drop_writable(ty);
555        inc(&mut self.core_funcs)
556    }
557
558    /// Declares a new `error-context.new` intrinsic.
559    pub fn error_context_new<O>(&mut self, options: O) -> u32
560    where
561        O: IntoIterator<Item = CanonicalOption>,
562        O::IntoIter: ExactSizeIterator,
563    {
564        self.canonical_functions().error_context_new(options);
565        inc(&mut self.core_funcs)
566    }
567
568    /// Declares a new `error-context.debug-message` intrinsic.
569    pub fn error_context_debug_message<O>(&mut self, options: O) -> u32
570    where
571        O: IntoIterator<Item = CanonicalOption>,
572        O::IntoIter: ExactSizeIterator,
573    {
574        self.canonical_functions()
575            .error_context_debug_message(options);
576        inc(&mut self.core_funcs)
577    }
578
579    /// Declares a new `error-context.drop` intrinsic.
580    pub fn error_context_drop(&mut self) -> u32 {
581        self.canonical_functions().error_context_drop();
582        inc(&mut self.core_funcs)
583    }
584
585    /// Declares a new `waitable-set.new` intrinsic.
586    pub fn waitable_set_new(&mut self) -> u32 {
587        self.canonical_functions().waitable_set_new();
588        inc(&mut self.core_funcs)
589    }
590
591    /// Declares a new `waitable-set.wait` intrinsic.
592    pub fn waitable_set_wait(&mut self, cancellable: bool, memory: u32) -> u32 {
593        self.canonical_functions()
594            .waitable_set_wait(cancellable, memory);
595        inc(&mut self.core_funcs)
596    }
597
598    /// Declares a new `waitable-set.poll` intrinsic.
599    pub fn waitable_set_poll(&mut self, cancellable: bool, memory: u32) -> u32 {
600        self.canonical_functions()
601            .waitable_set_poll(cancellable, memory);
602        inc(&mut self.core_funcs)
603    }
604
605    /// Declares a new `waitable-set.drop` intrinsic.
606    pub fn waitable_set_drop(&mut self) -> u32 {
607        self.canonical_functions().waitable_set_drop();
608        inc(&mut self.core_funcs)
609    }
610
611    /// Declares a new `waitable.join` intrinsic.
612    pub fn waitable_join(&mut self) -> u32 {
613        self.canonical_functions().waitable_join();
614        inc(&mut self.core_funcs)
615    }
616
617    /// Declares a new `thread.index` intrinsic.
618    pub fn thread_index(&mut self) -> u32 {
619        self.canonical_functions().thread_index();
620        inc(&mut self.core_funcs)
621    }
622
623    /// Declares a new `thread.new_indirect` intrinsic.
624    pub fn thread_new_indirect(&mut self, func_ty_idx: u32, table_index: u32) -> u32 {
625        self.canonical_functions()
626            .thread_new_indirect(func_ty_idx, table_index);
627        inc(&mut self.core_funcs)
628    }
629
630    /// Declares a new `thread.switch-to` intrinsic.
631    pub fn thread_switch_to(&mut self, cancellable: bool) -> u32 {
632        self.canonical_functions().thread_switch_to(cancellable);
633        inc(&mut self.core_funcs)
634    }
635
636    /// Declares a new `thread.suspend` intrinsic.
637    pub fn thread_suspend(&mut self, cancellable: bool) -> u32 {
638        self.canonical_functions().thread_suspend(cancellable);
639        inc(&mut self.core_funcs)
640    }
641
642    /// Declares a new `thread.resume-later` intrinsic.
643    pub fn thread_resume_later(&mut self) -> u32 {
644        self.canonical_functions().thread_resume_later();
645        inc(&mut self.core_funcs)
646    }
647
648    /// Declares a new `thread.yield-to` intrinsic.
649    pub fn thread_yield_to(&mut self, cancellable: bool) -> u32 {
650        self.canonical_functions().thread_yield_to(cancellable);
651        inc(&mut self.core_funcs)
652    }
653
654    /// Adds a new custom section to this component.
655    pub fn custom_section(&mut self, section: &CustomSection<'_>) {
656        self.flush();
657        self.component.section(section);
658    }
659
660    /// Adds a new custom section to this component.
661    pub fn raw_custom_section(&mut self, section: &[u8]) {
662        self.flush();
663        self.component.section(&RawCustomSection(section));
664    }
665}
666
667// Helper macro to generate methods on `ComponentBuilder` to get specific
668// section encoders that automatically flush and write out prior sections as
669// necessary.
670macro_rules! section_accessors {
671    ($($method:ident => $section:ident)*) => (
672        #[derive(Debug, Default)]
673        enum LastSection {
674            #[default]
675            None,
676            $($section($section),)*
677        }
678
679        impl ComponentBuilder {
680            $(
681                fn $method(&mut self) -> &mut $section {
682                    match &self.last_section {
683                        // The last encoded section matches the section that's
684                        // being requested, so no change is necessary.
685                        LastSection::$section(_) => {}
686
687                        // Otherwise the last section didn't match this section,
688                        // so flush any prior section if needed and start
689                        // encoding the desired section of this method.
690                        _ => {
691                            self.flush();
692                            self.last_section = LastSection::$section($section::new());
693                        }
694                    }
695                    match &mut self.last_section {
696                        LastSection::$section(ret) => ret,
697                        _ => unreachable!()
698                    }
699                }
700            )*
701
702            /// Writes out the last section into the final component binary if
703            /// there is a section specified, otherwise does nothing.
704            fn flush(&mut self) {
705                match mem::take(&mut self.last_section) {
706                    LastSection::None => {}
707                    $(
708                        LastSection::$section(section) => {
709                            self.component.section(&section);
710                        }
711                    )*
712                }
713            }
714
715        }
716    )
717}
718
719section_accessors! {
720    component_instances => ComponentInstanceSection
721    instances => InstanceSection
722    canonical_functions => CanonicalFunctionSection
723    aliases => ComponentAliasSection
724    exports => ComponentExportSection
725    imports => ComponentImportSection
726    types => ComponentTypeSection
727    core_types => CoreTypeSection
728}
729
730fn inc(idx: &mut u32) -> u32 {
731    let ret = *idx;
732    *idx += 1;
733    ret
734}