1use crate::component::*;
2use crate::{ExportKind, Module, NameMap, RawSection, ValType};
3use alloc::format;
4use alloc::vec::Vec;
5use core::mem;
6
7#[derive(Debug, Default)]
15pub struct ComponentBuilder {
16 component: Component,
18
19 last_section: LastSection,
26
27 core_modules: Namespace,
29 core_funcs: Namespace,
30 core_types: Namespace,
31 core_memories: Namespace,
32 core_tables: Namespace,
33 core_instances: Namespace,
34 core_tags: Namespace,
35 core_globals: Namespace,
36
37 funcs: Namespace,
39 instances: Namespace,
40 types: Namespace,
41 components: Namespace,
42 values: Namespace,
43}
44
45impl ComponentBuilder {
46 pub fn core_module_count(&self) -> u32 {
48 self.core_modules.count
49 }
50
51 pub fn core_func_count(&self) -> u32 {
53 self.core_funcs.count
54 }
55
56 pub fn core_type_count(&self) -> u32 {
58 self.core_types.count
59 }
60
61 pub fn core_memory_count(&self) -> u32 {
63 self.core_memories.count
64 }
65
66 pub fn core_table_count(&self) -> u32 {
68 self.core_tables.count
69 }
70
71 pub fn core_instance_count(&self) -> u32 {
73 self.core_instances.count
74 }
75
76 pub fn core_tag_count(&self) -> u32 {
78 self.core_tags.count
79 }
80
81 pub fn core_global_count(&self) -> u32 {
83 self.core_globals.count
84 }
85
86 pub fn func_count(&self) -> u32 {
88 self.funcs.count
89 }
90
91 pub fn instance_count(&self) -> u32 {
93 self.instances.count
94 }
95
96 pub fn value_count(&self) -> u32 {
98 self.values.count
99 }
100
101 pub fn component_count(&self) -> u32 {
103 self.components.count
104 }
105
106 pub fn type_count(&self) -> u32 {
108 self.types.count
109 }
110
111 pub fn append_names(&mut self) {
113 let mut names = ComponentNameSection::new();
114 if !self.core_funcs.names.is_empty() {
115 names.core_funcs(&self.core_funcs.names);
116 }
117 if !self.core_tables.names.is_empty() {
118 names.core_tables(&self.core_tables.names);
119 }
120 if !self.core_memories.names.is_empty() {
121 names.core_memories(&self.core_memories.names);
122 }
123 if !self.core_globals.names.is_empty() {
124 names.core_globals(&self.core_globals.names);
125 }
126 if !self.core_tags.names.is_empty() {
127 names.core_tags(&self.core_tags.names);
128 }
129 if !self.core_types.names.is_empty() {
130 names.core_types(&self.core_types.names);
131 }
132 if !self.core_modules.names.is_empty() {
133 names.core_modules(&self.core_modules.names);
134 }
135 if !self.core_instances.names.is_empty() {
136 names.core_instances(&self.core_instances.names);
137 }
138 if !self.instances.names.is_empty() {
139 names.instances(&self.instances.names);
140 }
141 if !self.funcs.names.is_empty() {
142 names.funcs(&self.funcs.names);
143 }
144 if !self.types.names.is_empty() {
145 names.types(&self.types.names);
146 }
147 if !self.components.names.is_empty() {
148 names.components(&self.components.names);
149 }
150 if !self.instances.names.is_empty() {
151 names.instances(&self.instances.names);
152 }
153 if !names.is_empty() {
154 self.custom_section(&names.as_custom());
155 }
156 }
157
158 pub fn finish(mut self) -> Vec<u8> {
161 self.flush();
162 self.component.finish()
163 }
164
165 pub fn core_module(&mut self, debug_name: Option<&str>, module: &Module) -> u32 {
167 self.flush();
168 self.component.section(&ModuleSection(module));
169 self.core_modules.add(debug_name)
170 }
171
172 pub fn core_module_raw(&mut self, debug_name: Option<&str>, module: &[u8]) -> u32 {
174 self.flush();
175 self.component.section(&RawSection {
176 id: ComponentSectionId::CoreModule.into(),
177 data: module,
178 });
179 self.core_modules.add(debug_name)
180 }
181
182 pub fn core_instantiate<'a, A>(
187 &mut self,
188 debug_name: Option<&str>,
189 module_index: u32,
190 args: A,
191 ) -> u32
192 where
193 A: IntoIterator<Item = (&'a str, ModuleArg)>,
194 A::IntoIter: ExactSizeIterator,
195 {
196 self.instances().instantiate(module_index, args);
197 self.core_instances.add(debug_name)
198 }
199
200 pub fn core_instantiate_exports<'a, E>(&mut self, debug_name: Option<&str>, exports: E) -> u32
204 where
205 E: IntoIterator<Item = (&'a str, ExportKind, u32)>,
206 E::IntoIter: ExactSizeIterator,
207 {
208 self.instances().export_items(exports);
209 self.core_instances.add(debug_name)
210 }
211
212 pub fn core_alias_export(
217 &mut self,
218 debug_name: Option<&str>,
219 instance: u32,
220 name: &str,
221 kind: ExportKind,
222 ) -> u32 {
223 self.alias(
224 debug_name,
225 Alias::CoreInstanceExport {
226 instance,
227 kind,
228 name,
229 },
230 )
231 }
232
233 pub fn alias(&mut self, debug_name: Option<&str>, alias: Alias<'_>) -> u32 {
235 self.aliases().alias(alias);
236 match alias {
237 Alias::InstanceExport { kind, .. } => self.inc_kind(debug_name, kind),
238 Alias::CoreInstanceExport { kind, .. } => self.inc_core_kind(debug_name, kind),
239 Alias::Outer {
240 kind: ComponentOuterAliasKind::Type,
241 ..
242 } => self.types.add(debug_name),
243 Alias::Outer {
244 kind: ComponentOuterAliasKind::CoreModule,
245 ..
246 } => self.core_modules.add(debug_name),
247 Alias::Outer {
248 kind: ComponentOuterAliasKind::Component,
249 ..
250 } => self.components.add(debug_name),
251 Alias::Outer {
252 kind: ComponentOuterAliasKind::CoreType,
253 ..
254 } => self.core_types.add(debug_name),
255 }
256 }
257
258 pub fn alias_export(&mut self, instance: u32, name: &str, kind: ComponentExportKind) -> u32 {
265 self.alias(
266 Some(name),
267 Alias::InstanceExport {
268 instance,
269 kind,
270 name,
271 },
272 )
273 }
274
275 fn inc_kind(&mut self, debug_name: Option<&str>, kind: ComponentExportKind) -> u32 {
276 match kind {
277 ComponentExportKind::Func => self.funcs.add(debug_name),
278 ComponentExportKind::Module => self.core_modules.add(debug_name),
279 ComponentExportKind::Type => self.types.add(debug_name),
280 ComponentExportKind::Component => self.components.add(debug_name),
281 ComponentExportKind::Instance => self.instances.add(debug_name),
282 ComponentExportKind::Value => self.values.add(debug_name),
283 }
284 }
285
286 fn inc_core_kind(&mut self, debug_name: Option<&str>, kind: ExportKind) -> u32 {
287 match kind {
288 ExportKind::Func => self.core_funcs.add(debug_name),
289 ExportKind::Table => self.core_tables.add(debug_name),
290 ExportKind::Memory => self.core_memories.add(debug_name),
291 ExportKind::Global => self.core_globals.add(debug_name),
292 ExportKind::Tag => self.core_tags.add(debug_name),
293 }
294 }
295
296 pub fn lower_func<O>(&mut self, debug_name: Option<&str>, func_index: u32, options: O) -> u32
301 where
302 O: IntoIterator<Item = CanonicalOption>,
303 O::IntoIter: ExactSizeIterator,
304 {
305 self.canonical_functions().lower(func_index, options);
306 self.core_funcs.add(debug_name)
307 }
308
309 pub fn lift_func<O>(
314 &mut self,
315 debug_name: Option<&str>,
316 core_func_index: u32,
317 type_index: u32,
318 options: O,
319 ) -> u32
320 where
321 O: IntoIterator<Item = CanonicalOption>,
322 O::IntoIter: ExactSizeIterator,
323 {
324 self.canonical_functions()
325 .lift(core_func_index, type_index, options);
326 self.funcs.add(debug_name)
327 }
328
329 pub fn import<'a>(
331 &mut self,
332 name: impl Into<ComponentExternName<'a>>,
333 ty: ComponentTypeRef,
334 ) -> u32 {
335 let name = name.into();
336 let ret = match &ty {
337 ComponentTypeRef::Instance(_) => self.instances.add(Some(&name.name)),
338 ComponentTypeRef::Func(_) => self.funcs.add(Some(&name.name)),
339 ComponentTypeRef::Type(..) => self.types.add(Some(&name.name)),
340 ComponentTypeRef::Component(_) => self.components.add(Some(&name.name)),
341 ComponentTypeRef::Module(_) => self.core_modules.add(Some(&name.name)),
342 ComponentTypeRef::Value(_) => self.values.add(Some(&name.name)),
343 };
344 self.imports().import(name, ty);
345 ret
346 }
347
348 pub fn export<'a>(
354 &mut self,
355 name: impl Into<ComponentExternName<'a>>,
356 kind: ComponentExportKind,
357 idx: u32,
358 ty: Option<ComponentTypeRef>,
359 ) -> u32 {
360 let name = name.into();
361 self.exports().export(name.clone(), kind, idx, ty);
362 self.inc_kind(Some(&name.name), kind)
363 }
364
365 pub fn core_type(&mut self, debug_name: Option<&str>) -> (u32, ComponentCoreTypeEncoder<'_>) {
367 (self.core_types.add(debug_name), self.core_types().ty())
368 }
369
370 pub fn ty(&mut self, debug_name: Option<&str>) -> (u32, ComponentTypeEncoder<'_>) {
372 (self.types.add(debug_name), self.types().ty())
373 }
374
375 pub fn type_instance(&mut self, debug_name: Option<&str>, ty: &InstanceType) -> u32 {
377 self.types().instance(ty);
378 self.types.add(debug_name)
379 }
380
381 pub fn type_component(&mut self, debug_name: Option<&str>, ty: &ComponentType) -> u32 {
383 self.types().component(ty);
384 self.types.add(debug_name)
385 }
386
387 pub fn type_defined(
389 &mut self,
390 debug_name: Option<&str>,
391 ) -> (u32, ComponentDefinedTypeEncoder<'_>) {
392 (self.types.add(debug_name), self.types().defined_type())
393 }
394
395 pub fn type_function(
397 &mut self,
398 debug_name: Option<&str>,
399 ) -> (u32, ComponentFuncTypeEncoder<'_>) {
400 (self.types.add(debug_name), self.types().function())
401 }
402
403 pub fn type_resource(
405 &mut self,
406 debug_name: Option<&str>,
407 rep: ValType,
408 dtor: Option<u32>,
409 ) -> u32 {
410 self.types().resource(rep, dtor);
411 self.types.add(debug_name)
412 }
413
414 pub fn component(&mut self, debug_name: Option<&str>, mut builder: ComponentBuilder) -> u32 {
416 builder.flush();
417 self.flush();
418 self.component
419 .section(&NestedComponentSection(&builder.component));
420 self.components.add(debug_name)
421 }
422
423 pub fn component_raw(&mut self, debug_name: Option<&str>, data: &[u8]) -> u32 {
425 let raw_section = RawSection {
426 id: ComponentSectionId::Component.into(),
427 data,
428 };
429 self.flush();
430 self.component.section(&raw_section);
431 self.components.add(debug_name)
432 }
433
434 pub fn instantiate<A, S>(
436 &mut self,
437 debug_name: Option<&str>,
438 component_index: u32,
439 args: A,
440 ) -> u32
441 where
442 A: IntoIterator<Item = (S, ComponentExportKind, u32)>,
443 A::IntoIter: ExactSizeIterator,
444 S: AsRef<str>,
445 {
446 self.component_instances()
447 .instantiate(component_index, args);
448 self.instances.add(debug_name)
449 }
450
451 pub fn resource_drop(&mut self, ty: u32) -> u32 {
453 self.canonical_functions().resource_drop(ty);
454 self.core_funcs.add(Some("resource.drop"))
455 }
456
457 pub fn resource_drop_async(&mut self, ty: u32) -> u32 {
459 self.canonical_functions().resource_drop_async(ty);
460 self.core_funcs.add(Some("resource.drop async"))
461 }
462
463 pub fn resource_new(&mut self, ty: u32) -> u32 {
465 self.canonical_functions().resource_new(ty);
466 self.core_funcs.add(Some("resource.new"))
467 }
468
469 pub fn resource_rep(&mut self, ty: u32) -> u32 {
471 self.canonical_functions().resource_rep(ty);
472 self.core_funcs.add(Some("resource.rep"))
473 }
474
475 pub fn thread_spawn_ref(&mut self, ty: u32) -> u32 {
477 self.canonical_functions().thread_spawn_ref(ty);
478 self.core_funcs.add(Some("thread.spawn-ref"))
479 }
480
481 pub fn thread_available_parallelism(&mut self) -> u32 {
483 self.canonical_functions().thread_available_parallelism();
484 self.core_funcs.add(Some("thread.available-parallelism"))
485 }
486
487 pub fn backpressure_inc(&mut self) -> u32 {
489 self.canonical_functions().backpressure_inc();
490 self.core_funcs.add(Some("backpressure.inc"))
491 }
492
493 pub fn backpressure_dec(&mut self) -> u32 {
495 self.canonical_functions().backpressure_dec();
496 self.core_funcs.add(Some("backpressure.dec"))
497 }
498
499 pub fn task_return<O>(&mut self, ty: Option<ComponentValType>, options: O) -> u32
501 where
502 O: IntoIterator<Item = CanonicalOption>,
503 O::IntoIter: ExactSizeIterator,
504 {
505 self.canonical_functions().task_return(ty, options);
506 self.core_funcs.add(Some("task.return"))
507 }
508
509 pub fn task_cancel(&mut self) -> u32 {
511 self.canonical_functions().task_cancel();
512 self.core_funcs.add(Some("task.cancel"))
513 }
514
515 pub fn context_get(&mut self, ty: ValType, i: u32) -> u32 {
517 self.canonical_functions().context_get(ty, i);
518 self.core_funcs.add(Some(&format!("context.get {i}")))
519 }
520
521 pub fn context_set(&mut self, ty: ValType, i: u32) -> u32 {
523 self.canonical_functions().context_set(ty, i);
524 self.core_funcs.add(Some(&format!("context.set {i}")))
525 }
526
527 pub fn thread_yield(&mut self, cancellable: bool) -> u32 {
529 self.canonical_functions().thread_yield(cancellable);
530 self.core_funcs.add(Some("thread.yield"))
531 }
532
533 pub fn subtask_drop(&mut self) -> u32 {
535 self.canonical_functions().subtask_drop();
536 self.core_funcs.add(Some("subtask.drop"))
537 }
538
539 pub fn subtask_cancel(&mut self, async_: bool) -> u32 {
541 self.canonical_functions().subtask_cancel(async_);
542 self.core_funcs.add(Some("subtask.cancel"))
543 }
544
545 pub fn stream_new(&mut self, ty: u32) -> u32 {
547 self.canonical_functions().stream_new(ty);
548 self.core_funcs.add(Some("stream.new"))
549 }
550
551 pub fn stream_read<O>(&mut self, ty: u32, options: O) -> u32
553 where
554 O: IntoIterator<Item = CanonicalOption>,
555 O::IntoIter: ExactSizeIterator,
556 {
557 self.canonical_functions().stream_read(ty, options);
558 self.core_funcs.add(Some("stream.read"))
559 }
560
561 pub fn stream_write<O>(&mut self, ty: u32, options: O) -> u32
563 where
564 O: IntoIterator<Item = CanonicalOption>,
565 O::IntoIter: ExactSizeIterator,
566 {
567 self.canonical_functions().stream_write(ty, options);
568 self.core_funcs.add(Some("stream.write"))
569 }
570
571 pub fn stream_cancel_read(&mut self, ty: u32, async_: bool) -> u32 {
573 self.canonical_functions().stream_cancel_read(ty, async_);
574 self.core_funcs.add(Some("stream.cancel-read"))
575 }
576
577 pub fn stream_cancel_write(&mut self, ty: u32, async_: bool) -> u32 {
579 self.canonical_functions().stream_cancel_write(ty, async_);
580 self.core_funcs.add(Some("stream.cancel-write"))
581 }
582
583 pub fn stream_drop_readable(&mut self, ty: u32) -> u32 {
585 self.canonical_functions().stream_drop_readable(ty);
586 self.core_funcs.add(Some("stream.drop-readable"))
587 }
588
589 pub fn stream_drop_writable(&mut self, ty: u32) -> u32 {
591 self.canonical_functions().stream_drop_writable(ty);
592 self.core_funcs.add(Some("stream.drop-writable"))
593 }
594
595 pub fn future_new(&mut self, ty: u32) -> u32 {
597 self.canonical_functions().future_new(ty);
598 self.core_funcs.add(Some("future.new"))
599 }
600
601 pub fn future_read<O>(&mut self, ty: u32, options: O) -> u32
603 where
604 O: IntoIterator<Item = CanonicalOption>,
605 O::IntoIter: ExactSizeIterator,
606 {
607 self.canonical_functions().future_read(ty, options);
608 self.core_funcs.add(Some("future.read"))
609 }
610
611 pub fn future_write<O>(&mut self, ty: u32, options: O) -> u32
613 where
614 O: IntoIterator<Item = CanonicalOption>,
615 O::IntoIter: ExactSizeIterator,
616 {
617 self.canonical_functions().future_write(ty, options);
618 self.core_funcs.add(Some("future.write"))
619 }
620
621 pub fn future_cancel_read(&mut self, ty: u32, async_: bool) -> u32 {
623 self.canonical_functions().future_cancel_read(ty, async_);
624 self.core_funcs.add(Some("future.cancel-read"))
625 }
626
627 pub fn future_cancel_write(&mut self, ty: u32, async_: bool) -> u32 {
629 self.canonical_functions().future_cancel_write(ty, async_);
630 self.core_funcs.add(Some("future.cancel-write"))
631 }
632
633 pub fn future_drop_readable(&mut self, ty: u32) -> u32 {
635 self.canonical_functions().future_drop_readable(ty);
636 self.core_funcs.add(Some("future.drop-readable"))
637 }
638
639 pub fn future_drop_writable(&mut self, ty: u32) -> u32 {
641 self.canonical_functions().future_drop_writable(ty);
642 self.core_funcs.add(Some("future.drop-writable"))
643 }
644
645 pub fn error_context_new<O>(&mut self, options: O) -> u32
647 where
648 O: IntoIterator<Item = CanonicalOption>,
649 O::IntoIter: ExactSizeIterator,
650 {
651 self.canonical_functions().error_context_new(options);
652 self.core_funcs.add(Some("error-context.new"))
653 }
654
655 pub fn error_context_debug_message<O>(&mut self, options: O) -> u32
657 where
658 O: IntoIterator<Item = CanonicalOption>,
659 O::IntoIter: ExactSizeIterator,
660 {
661 self.canonical_functions()
662 .error_context_debug_message(options);
663 self.core_funcs.add(Some("error-context.debug-message"))
664 }
665
666 pub fn error_context_drop(&mut self) -> u32 {
668 self.canonical_functions().error_context_drop();
669 self.core_funcs.add(Some("error-context.drop"))
670 }
671
672 pub fn waitable_set_new(&mut self) -> u32 {
674 self.canonical_functions().waitable_set_new();
675 self.core_funcs.add(Some("waitable-set.new"))
676 }
677
678 pub fn waitable_set_wait(&mut self, cancellable: bool, memory: u32) -> u32 {
680 self.canonical_functions()
681 .waitable_set_wait(cancellable, memory);
682 self.core_funcs.add(Some("waitable-set.wait"))
683 }
684
685 pub fn waitable_set_poll(&mut self, cancellable: bool, memory: u32) -> u32 {
687 self.canonical_functions()
688 .waitable_set_poll(cancellable, memory);
689 self.core_funcs.add(Some("waitable-set.poll"))
690 }
691
692 pub fn waitable_set_drop(&mut self) -> u32 {
694 self.canonical_functions().waitable_set_drop();
695 self.core_funcs.add(Some("waitable-set.drop"))
696 }
697
698 pub fn waitable_join(&mut self) -> u32 {
700 self.canonical_functions().waitable_join();
701 self.core_funcs.add(Some("waitable.join"))
702 }
703
704 pub fn thread_index(&mut self) -> u32 {
706 self.canonical_functions().thread_index();
707 self.core_funcs.add(Some("thread.index"))
708 }
709
710 pub fn thread_new_indirect(&mut self, func_ty_idx: u32, table_index: u32) -> u32 {
712 self.canonical_functions()
713 .thread_new_indirect(func_ty_idx, table_index);
714 self.core_funcs.add(Some("thread.new-indirect"))
715 }
716
717 pub fn thread_suspend_to_suspended(&mut self, cancellable: bool) -> u32 {
719 self.canonical_functions()
720 .thread_suspend_to_suspended(cancellable);
721 self.core_funcs.add(Some("thread.suspend-to-suspended"))
722 }
723
724 pub fn thread_suspend_to(&mut self, cancellable: bool) -> u32 {
726 self.canonical_functions().thread_suspend_to(cancellable);
727 self.core_funcs.add(Some("thread.suspend-to"))
728 }
729
730 pub fn thread_suspend(&mut self, cancellable: bool) -> u32 {
732 self.canonical_functions().thread_suspend(cancellable);
733 self.core_funcs.add(Some("thread.suspend"))
734 }
735
736 pub fn thread_unsuspend(&mut self) -> u32 {
738 self.canonical_functions().thread_unsuspend();
739 self.core_funcs.add(Some("thread.unsuspend"))
740 }
741
742 pub fn thread_yield_to_suspended(&mut self, cancellable: bool) -> u32 {
744 self.canonical_functions()
745 .thread_yield_to_suspended(cancellable);
746 self.core_funcs.add(Some("thread.yield-to-suspended"))
747 }
748
749 pub fn custom_section(&mut self, section: &CustomSection<'_>) {
751 self.flush();
752 self.component.section(section);
753 }
754
755 pub fn raw_custom_section(&mut self, section: &[u8]) {
757 self.flush();
758 self.component.section(&RawCustomSection(section));
759 }
760}
761
762macro_rules! section_accessors {
766 ($($method:ident => $section:ident)*) => (
767 #[derive(Debug, Default)]
768 enum LastSection {
769 #[default]
770 None,
771 $($section($section),)*
772 }
773
774 impl ComponentBuilder {
775 $(
776 fn $method(&mut self) -> &mut $section {
777 match &self.last_section {
778 LastSection::$section(_) => {}
781
782 _ => {
786 self.flush();
787 self.last_section = LastSection::$section($section::new());
788 }
789 }
790 match &mut self.last_section {
791 LastSection::$section(ret) => ret,
792 _ => unreachable!()
793 }
794 }
795 )*
796
797 fn flush(&mut self) {
800 match mem::take(&mut self.last_section) {
801 LastSection::None => {}
802 $(
803 LastSection::$section(section) => {
804 self.component.section(§ion);
805 }
806 )*
807 }
808 }
809
810 }
811 )
812}
813
814section_accessors! {
815 component_instances => ComponentInstanceSection
816 instances => InstanceSection
817 canonical_functions => CanonicalFunctionSection
818 aliases => ComponentAliasSection
819 exports => ComponentExportSection
820 imports => ComponentImportSection
821 types => ComponentTypeSection
822 core_types => CoreTypeSection
823}
824
825#[derive(Debug, Default)]
826struct Namespace {
827 count: u32,
828 names: NameMap,
829}
830
831impl Namespace {
832 fn add(&mut self, name: Option<&str>) -> u32 {
833 let ret = self.count;
834 self.count += 1;
835 if let Some(name) = name {
836 self.names.append(ret, name);
837 }
838 ret
839 }
840}