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 start(&mut self, function_index: u32, args: Vec<u32>, results: u32) -> u32 {
468 self.flush();
473 self.component.section(&ComponentStartSection {
474 function_index,
475 args,
476 results,
477 });
478 let base = self.values.count;
479 for _ in 0..results {
480 self.values.add(None);
481 }
482 base
483 }
484
485 pub fn instantiate_exports<'a, E, N>(&mut self, debug_name: Option<&str>, exports: E) -> u32
489 where
490 E: IntoIterator<Item = (N, ComponentExportKind, u32)>,
491 E::IntoIter: ExactSizeIterator,
492 N: Into<ComponentExternName<'a>>,
493 {
494 self.component_instances().export_items(exports);
495 self.instances.add(debug_name)
496 }
497
498 pub fn resource_drop(&mut self, ty: u32) -> u32 {
500 self.canonical_functions().resource_drop(ty);
501 self.core_funcs.add(Some("resource.drop"))
502 }
503
504 pub fn resource_new(&mut self, ty: u32) -> u32 {
506 self.canonical_functions().resource_new(ty);
507 self.core_funcs.add(Some("resource.new"))
508 }
509
510 pub fn resource_rep(&mut self, ty: u32) -> u32 {
512 self.canonical_functions().resource_rep(ty);
513 self.core_funcs.add(Some("resource.rep"))
514 }
515
516 pub fn thread_spawn_ref(&mut self, ty: u32) -> u32 {
518 self.canonical_functions().thread_spawn_ref(ty);
519 self.core_funcs.add(Some("thread.spawn-ref"))
520 }
521
522 pub fn thread_available_parallelism(&mut self) -> u32 {
524 self.canonical_functions().thread_available_parallelism();
525 self.core_funcs.add(Some("thread.available-parallelism"))
526 }
527
528 pub fn backpressure_inc(&mut self) -> u32 {
530 self.canonical_functions().backpressure_inc();
531 self.core_funcs.add(Some("backpressure.inc"))
532 }
533
534 pub fn backpressure_dec(&mut self) -> u32 {
536 self.canonical_functions().backpressure_dec();
537 self.core_funcs.add(Some("backpressure.dec"))
538 }
539
540 pub fn task_return<O>(&mut self, ty: Option<ComponentValType>, options: O) -> u32
542 where
543 O: IntoIterator<Item = CanonicalOption>,
544 O::IntoIter: ExactSizeIterator,
545 {
546 self.canonical_functions().task_return(ty, options);
547 self.core_funcs.add(Some("task.return"))
548 }
549
550 pub fn task_cancel(&mut self) -> u32 {
552 self.canonical_functions().task_cancel();
553 self.core_funcs.add(Some("task.cancel"))
554 }
555
556 pub fn context_get(&mut self, ty: ValType, i: u32) -> u32 {
558 self.canonical_functions().context_get(ty, i);
559 self.core_funcs.add(Some(&format!("context.get {i}")))
560 }
561
562 pub fn context_set(&mut self, ty: ValType, i: u32) -> u32 {
564 self.canonical_functions().context_set(ty, i);
565 self.core_funcs.add(Some(&format!("context.set {i}")))
566 }
567
568 pub fn subtask_drop(&mut self) -> u32 {
570 self.canonical_functions().subtask_drop();
571 self.core_funcs.add(Some("subtask.drop"))
572 }
573
574 pub fn subtask_cancel(&mut self, async_: bool) -> u32 {
576 self.canonical_functions().subtask_cancel(async_);
577 self.core_funcs.add(Some("subtask.cancel"))
578 }
579
580 pub fn stream_new(&mut self, ty: u32) -> u32 {
582 self.canonical_functions().stream_new(ty);
583 self.core_funcs.add(Some("stream.new"))
584 }
585
586 pub fn stream_read<O>(&mut self, ty: u32, options: O) -> u32
588 where
589 O: IntoIterator<Item = CanonicalOption>,
590 O::IntoIter: ExactSizeIterator,
591 {
592 self.canonical_functions().stream_read(ty, options);
593 self.core_funcs.add(Some("stream.read"))
594 }
595
596 pub fn stream_write<O>(&mut self, ty: u32, options: O) -> u32
598 where
599 O: IntoIterator<Item = CanonicalOption>,
600 O::IntoIter: ExactSizeIterator,
601 {
602 self.canonical_functions().stream_write(ty, options);
603 self.core_funcs.add(Some("stream.write"))
604 }
605
606 pub fn stream_forward(&mut self, ty: u32) -> u32 {
608 self.canonical_functions().stream_forward(ty);
609 self.core_funcs.add(Some("stream.forward"))
610 }
611
612 pub fn stream_cancel_read(&mut self, ty: u32, async_: bool) -> u32 {
614 self.canonical_functions().stream_cancel_read(ty, async_);
615 self.core_funcs.add(Some("stream.cancel-read"))
616 }
617
618 pub fn stream_cancel_write(&mut self, ty: u32, async_: bool) -> u32 {
620 self.canonical_functions().stream_cancel_write(ty, async_);
621 self.core_funcs.add(Some("stream.cancel-write"))
622 }
623
624 pub fn stream_drop_readable(&mut self, ty: u32) -> u32 {
626 self.canonical_functions().stream_drop_readable(ty);
627 self.core_funcs.add(Some("stream.drop-readable"))
628 }
629
630 pub fn stream_drop_writable(&mut self, ty: u32) -> u32 {
632 self.canonical_functions().stream_drop_writable(ty);
633 self.core_funcs.add(Some("stream.drop-writable"))
634 }
635
636 pub fn future_new(&mut self, ty: u32) -> u32 {
638 self.canonical_functions().future_new(ty);
639 self.core_funcs.add(Some("future.new"))
640 }
641
642 pub fn future_read<O>(&mut self, ty: u32, options: O) -> u32
644 where
645 O: IntoIterator<Item = CanonicalOption>,
646 O::IntoIter: ExactSizeIterator,
647 {
648 self.canonical_functions().future_read(ty, options);
649 self.core_funcs.add(Some("future.read"))
650 }
651
652 pub fn future_write<O>(&mut self, ty: u32, options: O) -> u32
654 where
655 O: IntoIterator<Item = CanonicalOption>,
656 O::IntoIter: ExactSizeIterator,
657 {
658 self.canonical_functions().future_write(ty, options);
659 self.core_funcs.add(Some("future.write"))
660 }
661
662 pub fn future_forward(&mut self, ty: u32) -> u32 {
664 self.canonical_functions().future_forward(ty);
665 self.core_funcs.add(Some("future.forward"))
666 }
667
668 pub fn future_cancel_read(&mut self, ty: u32, async_: bool) -> u32 {
670 self.canonical_functions().future_cancel_read(ty, async_);
671 self.core_funcs.add(Some("future.cancel-read"))
672 }
673
674 pub fn future_cancel_write(&mut self, ty: u32, async_: bool) -> u32 {
676 self.canonical_functions().future_cancel_write(ty, async_);
677 self.core_funcs.add(Some("future.cancel-write"))
678 }
679
680 pub fn future_drop_readable(&mut self, ty: u32) -> u32 {
682 self.canonical_functions().future_drop_readable(ty);
683 self.core_funcs.add(Some("future.drop-readable"))
684 }
685
686 pub fn future_drop_writable(&mut self, ty: u32) -> u32 {
688 self.canonical_functions().future_drop_writable(ty);
689 self.core_funcs.add(Some("future.drop-writable"))
690 }
691
692 pub fn error_context_new<O>(&mut self, options: O) -> u32
694 where
695 O: IntoIterator<Item = CanonicalOption>,
696 O::IntoIter: ExactSizeIterator,
697 {
698 self.canonical_functions().error_context_new(options);
699 self.core_funcs.add(Some("error-context.new"))
700 }
701
702 pub fn error_context_debug_message<O>(&mut self, options: O) -> u32
704 where
705 O: IntoIterator<Item = CanonicalOption>,
706 O::IntoIter: ExactSizeIterator,
707 {
708 self.canonical_functions()
709 .error_context_debug_message(options);
710 self.core_funcs.add(Some("error-context.debug-message"))
711 }
712
713 pub fn error_context_drop(&mut self) -> u32 {
715 self.canonical_functions().error_context_drop();
716 self.core_funcs.add(Some("error-context.drop"))
717 }
718
719 pub fn waitable_set_new(&mut self) -> u32 {
721 self.canonical_functions().waitable_set_new();
722 self.core_funcs.add(Some("waitable-set.new"))
723 }
724
725 pub fn waitable_set_wait(&mut self, memory: u32) -> u32 {
727 self.canonical_functions().waitable_set_wait(memory);
728 self.core_funcs.add(Some("waitable-set.wait"))
729 }
730
731 pub fn waitable_set_poll(&mut self, memory: u32) -> u32 {
733 self.canonical_functions().waitable_set_poll(memory);
734 self.core_funcs.add(Some("waitable-set.poll"))
735 }
736
737 pub fn waitable_set_drop(&mut self) -> u32 {
739 self.canonical_functions().waitable_set_drop();
740 self.core_funcs.add(Some("waitable-set.drop"))
741 }
742
743 pub fn waitable_join(&mut self) -> u32 {
745 self.canonical_functions().waitable_join();
746 self.core_funcs.add(Some("waitable.join"))
747 }
748
749 pub fn thread_index(&mut self) -> u32 {
751 self.canonical_functions().thread_index();
752 self.core_funcs.add(Some("thread.index"))
753 }
754
755 pub fn thread_new_indirect(&mut self, func_ty_idx: u32, table_index: u32) -> u32 {
757 self.canonical_functions()
758 .thread_new_indirect(func_ty_idx, table_index);
759 self.core_funcs.add(Some("thread.new-indirect"))
760 }
761
762 pub fn thread_resume_later(&mut self) -> u32 {
764 self.canonical_functions().thread_resume_later();
765 self.core_funcs.add(Some("thread.resume-later"))
766 }
767
768 pub fn thread_suspend(&mut self) -> u32 {
770 self.canonical_functions().thread_suspend();
771 self.core_funcs.add(Some("thread.suspend"))
772 }
773
774 pub fn thread_yield(&mut self) -> u32 {
776 self.canonical_functions().thread_yield();
777 self.core_funcs.add(Some("thread.yield"))
778 }
779
780 pub fn thread_suspend_then_resume(&mut self) -> u32 {
782 self.canonical_functions().thread_suspend_then_resume();
783 self.core_funcs.add(Some("thread.suspend-then-resume"))
784 }
785
786 pub fn thread_yield_then_resume(&mut self) -> u32 {
788 self.canonical_functions().thread_yield_then_resume();
789 self.core_funcs.add(Some("thread.yield-then-resume"))
790 }
791
792 pub fn thread_suspend_then_promote(&mut self) -> u32 {
794 self.canonical_functions().thread_suspend_then_promote();
795 self.core_funcs.add(Some("thread.suspend-then-promote"))
796 }
797
798 pub fn thread_yield_then_promote(&mut self) -> u32 {
800 self.canonical_functions().thread_yield_then_promote();
801 self.core_funcs.add(Some("thread.yield-then-resume"))
802 }
803
804 pub fn custom_section(&mut self, section: &CustomSection<'_>) {
806 self.flush();
807 self.component.section(section);
808 }
809
810 pub fn raw_custom_section(&mut self, section: &[u8]) {
812 self.flush();
813 self.component.section(&RawCustomSection(section));
814 }
815}
816
817macro_rules! section_accessors {
821 ($($method:ident => $section:ident)*) => (
822 #[derive(Debug, Default)]
823 enum LastSection {
824 #[default]
825 None,
826 $($section($section),)*
827 }
828
829 impl ComponentBuilder {
830 $(
831 fn $method(&mut self) -> &mut $section {
832 match &self.last_section {
833 LastSection::$section(_) => {}
836
837 _ => {
841 self.flush();
842 self.last_section = LastSection::$section($section::new());
843 }
844 }
845 match &mut self.last_section {
846 LastSection::$section(ret) => ret,
847 _ => unreachable!()
848 }
849 }
850 )*
851
852 fn flush(&mut self) {
855 match mem::take(&mut self.last_section) {
856 LastSection::None => {}
857 $(
858 LastSection::$section(section) => {
859 self.component.section(§ion);
860 }
861 )*
862 }
863 }
864
865 }
866 )
867}
868
869section_accessors! {
870 component_instances => ComponentInstanceSection
871 instances => InstanceSection
872 canonical_functions => CanonicalFunctionSection
873 aliases => ComponentAliasSection
874 exports => ComponentExportSection
875 imports => ComponentImportSection
876 types => ComponentTypeSection
877 core_types => CoreTypeSection
878}
879
880#[derive(Debug, Default)]
881struct Namespace {
882 count: u32,
883 names: NameMap,
884}
885
886impl Namespace {
887 fn add(&mut self, name: Option<&str>) -> u32 {
888 let ret = self.count;
889 self.count += 1;
890 if let Some(name) = name {
891 self.names.append(ret, name);
892 }
893 ret
894 }
895}