1use crate::component::*;
2use crate::{ExportKind, Module, RawSection, ValType};
3use alloc::vec::Vec;
4use core::mem;
5
6#[derive(Debug, Default)]
14pub struct ComponentBuilder {
15 component: Component,
17
18 last_section: LastSection,
25
26 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 funcs: u32,
38 instances: u32,
39 types: u32,
40 components: u32,
41 values: u32,
42}
43
44impl ComponentBuilder {
45 pub fn core_module_count(&self) -> u32 {
47 self.core_modules
48 }
49
50 pub fn core_func_count(&self) -> u32 {
52 self.core_funcs
53 }
54
55 pub fn core_type_count(&self) -> u32 {
57 self.core_types
58 }
59
60 pub fn core_memory_count(&self) -> u32 {
62 self.core_memories
63 }
64
65 pub fn core_table_count(&self) -> u32 {
67 self.core_tables
68 }
69
70 pub fn core_instance_count(&self) -> u32 {
72 self.core_instances
73 }
74
75 pub fn core_tag_count(&self) -> u32 {
77 self.core_tags
78 }
79
80 pub fn core_global_count(&self) -> u32 {
82 self.core_globals
83 }
84
85 pub fn func_count(&self) -> u32 {
87 self.funcs
88 }
89
90 pub fn instance_count(&self) -> u32 {
92 self.instances
93 }
94
95 pub fn value_count(&self) -> u32 {
97 self.values
98 }
99
100 pub fn component_count(&self) -> u32 {
102 self.components
103 }
104
105 pub fn type_count(&self) -> u32 {
107 self.types
108 }
109
110 pub fn finish(mut self) -> Vec<u8> {
113 self.flush();
114 self.component.finish()
115 }
116
117 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 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 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 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 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 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 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 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 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 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 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 pub fn core_type(&mut self) -> (u32, ComponentCoreTypeEncoder<'_>) {
290 (inc(&mut self.core_types), self.core_types().ty())
291 }
292
293 pub fn ty(&mut self) -> (u32, ComponentTypeEncoder<'_>) {
295 (inc(&mut self.types), self.types().ty())
296 }
297
298 pub fn type_instance(&mut self, ty: &InstanceType) -> u32 {
300 self.types().instance(ty);
301 inc(&mut self.types)
302 }
303
304 pub fn type_component(&mut self, ty: &ComponentType) -> u32 {
306 self.types().component(ty);
307 inc(&mut self.types)
308 }
309
310 pub fn type_defined(&mut self) -> (u32, ComponentDefinedTypeEncoder<'_>) {
312 (inc(&mut self.types), self.types().defined_type())
313 }
314
315 pub fn type_function(&mut self) -> (u32, ComponentFuncTypeEncoder<'_>) {
317 (inc(&mut self.types), self.types().function())
318 }
319
320 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 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 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 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 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 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 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 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 pub fn thread_spawn(&mut self, ty: u32) -> u32 {
384 self.canonical_functions().thread_spawn(ty);
385 inc(&mut self.core_funcs)
386 }
387
388 pub fn thread_available_parallelism(&mut self) -> u32 {
390 self.canonical_functions().thread_available_parallelism();
391 inc(&mut self.core_funcs)
392 }
393
394 pub fn backpressure_set(&mut self) -> u32 {
396 self.canonical_functions().backpressure_set();
397 inc(&mut self.core_funcs)
398 }
399
400 pub fn task_return<O>(&mut self, ty: Option<ComponentValType>, options: O) -> u32
402 where
403 O: IntoIterator<Item = CanonicalOption>,
404 O::IntoIter: ExactSizeIterator,
405 {
406 self.canonical_functions().task_return(ty, options);
407 inc(&mut self.core_funcs)
408 }
409
410 pub fn yield_(&mut self, async_: bool) -> u32 {
412 self.canonical_functions().yield_(async_);
413 inc(&mut self.core_funcs)
414 }
415
416 pub fn subtask_drop(&mut self) -> u32 {
418 self.canonical_functions().subtask_drop();
419 inc(&mut self.core_funcs)
420 }
421
422 pub fn stream_new(&mut self, ty: u32) -> u32 {
424 self.canonical_functions().stream_new(ty);
425 inc(&mut self.core_funcs)
426 }
427
428 pub fn stream_read<O>(&mut self, ty: u32, options: O) -> u32
430 where
431 O: IntoIterator<Item = CanonicalOption>,
432 O::IntoIter: ExactSizeIterator,
433 {
434 self.canonical_functions().stream_read(ty, options);
435 inc(&mut self.core_funcs)
436 }
437
438 pub fn stream_write<O>(&mut self, ty: u32, options: O) -> u32
440 where
441 O: IntoIterator<Item = CanonicalOption>,
442 O::IntoIter: ExactSizeIterator,
443 {
444 self.canonical_functions().stream_write(ty, options);
445 inc(&mut self.core_funcs)
446 }
447
448 pub fn stream_cancel_read(&mut self, ty: u32, async_: bool) -> u32 {
450 self.canonical_functions().stream_cancel_read(ty, async_);
451 inc(&mut self.core_funcs)
452 }
453
454 pub fn stream_cancel_write(&mut self, ty: u32, async_: bool) -> u32 {
456 self.canonical_functions().stream_cancel_write(ty, async_);
457 inc(&mut self.core_funcs)
458 }
459
460 pub fn stream_close_readable(&mut self, ty: u32) -> u32 {
462 self.canonical_functions().stream_close_readable(ty);
463 inc(&mut self.core_funcs)
464 }
465
466 pub fn stream_close_writable(&mut self, ty: u32) -> u32 {
468 self.canonical_functions().stream_close_writable(ty);
469 inc(&mut self.core_funcs)
470 }
471
472 pub fn future_new(&mut self, ty: u32) -> u32 {
474 self.canonical_functions().future_new(ty);
475 inc(&mut self.core_funcs)
476 }
477
478 pub fn future_read<O>(&mut self, ty: u32, options: O) -> u32
480 where
481 O: IntoIterator<Item = CanonicalOption>,
482 O::IntoIter: ExactSizeIterator,
483 {
484 self.canonical_functions().future_read(ty, options);
485 inc(&mut self.core_funcs)
486 }
487
488 pub fn future_write<O>(&mut self, ty: u32, options: O) -> u32
490 where
491 O: IntoIterator<Item = CanonicalOption>,
492 O::IntoIter: ExactSizeIterator,
493 {
494 self.canonical_functions().future_write(ty, options);
495 inc(&mut self.core_funcs)
496 }
497
498 pub fn future_cancel_read(&mut self, ty: u32, async_: bool) -> u32 {
500 self.canonical_functions().future_cancel_read(ty, async_);
501 inc(&mut self.core_funcs)
502 }
503
504 pub fn future_cancel_write(&mut self, ty: u32, async_: bool) -> u32 {
506 self.canonical_functions().future_cancel_write(ty, async_);
507 inc(&mut self.core_funcs)
508 }
509
510 pub fn future_close_readable(&mut self, ty: u32) -> u32 {
512 self.canonical_functions().future_close_readable(ty);
513 inc(&mut self.core_funcs)
514 }
515
516 pub fn future_close_writable(&mut self, ty: u32) -> u32 {
518 self.canonical_functions().future_close_writable(ty);
519 inc(&mut self.core_funcs)
520 }
521
522 pub fn error_context_new<O>(&mut self, options: O) -> u32
524 where
525 O: IntoIterator<Item = CanonicalOption>,
526 O::IntoIter: ExactSizeIterator,
527 {
528 self.canonical_functions().error_context_new(options);
529 inc(&mut self.core_funcs)
530 }
531
532 pub fn error_context_debug_message<O>(&mut self, options: O) -> u32
534 where
535 O: IntoIterator<Item = CanonicalOption>,
536 O::IntoIter: ExactSizeIterator,
537 {
538 self.canonical_functions()
539 .error_context_debug_message(options);
540 inc(&mut self.core_funcs)
541 }
542
543 pub fn error_context_drop(&mut self) -> u32 {
545 self.canonical_functions().error_context_drop();
546 inc(&mut self.core_funcs)
547 }
548
549 pub fn waitable_set_new(&mut self) -> u32 {
551 self.canonical_functions().waitable_set_new();
552 inc(&mut self.core_funcs)
553 }
554
555 pub fn waitable_set_wait(&mut self, async_: bool, memory: u32) -> u32 {
557 self.canonical_functions().waitable_set_wait(async_, memory);
558 inc(&mut self.core_funcs)
559 }
560
561 pub fn waitable_set_poll(&mut self, async_: bool, memory: u32) -> u32 {
563 self.canonical_functions().waitable_set_poll(async_, memory);
564 inc(&mut self.core_funcs)
565 }
566
567 pub fn waitable_set_drop(&mut self) -> u32 {
569 self.canonical_functions().waitable_set_drop();
570 inc(&mut self.core_funcs)
571 }
572
573 pub fn waitable_join(&mut self) -> u32 {
575 self.canonical_functions().waitable_join();
576 inc(&mut self.core_funcs)
577 }
578
579 pub fn custom_section(&mut self, section: &CustomSection<'_>) {
581 self.flush();
582 self.component.section(section);
583 }
584
585 pub fn raw_custom_section(&mut self, section: &[u8]) {
587 self.flush();
588 self.component.section(&RawCustomSection(section));
589 }
590}
591
592macro_rules! section_accessors {
596 ($($method:ident => $section:ident)*) => (
597 #[derive(Debug, Default)]
598 enum LastSection {
599 #[default]
600 None,
601 $($section($section),)*
602 }
603
604 impl ComponentBuilder {
605 $(
606 fn $method(&mut self) -> &mut $section {
607 match &self.last_section {
608 LastSection::$section(_) => {}
611
612 _ => {
616 self.flush();
617 self.last_section = LastSection::$section($section::new());
618 }
619 }
620 match &mut self.last_section {
621 LastSection::$section(ret) => ret,
622 _ => unreachable!()
623 }
624 }
625 )*
626
627 fn flush(&mut self) {
630 match mem::take(&mut self.last_section) {
631 LastSection::None => {}
632 $(
633 LastSection::$section(section) => {
634 self.component.section(§ion);
635 }
636 )*
637 }
638 }
639
640 }
641 )
642}
643
644section_accessors! {
645 component_instances => ComponentInstanceSection
646 instances => InstanceSection
647 canonical_functions => CanonicalFunctionSection
648 aliases => ComponentAliasSection
649 exports => ComponentExportSection
650 imports => ComponentImportSection
651 types => ComponentTypeSection
652 core_types => CoreTypeSection
653}
654
655fn inc(idx: &mut u32) -> u32 {
656 let ret = *idx;
657 *idx += 1;
658 ret
659}