Coverage Report

Created: 2025-06-23 13:53

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