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_new(&mut self, ty: u32) -> u32 {
459 self.canonical_functions().resource_new(ty);
460 self.core_funcs.add(Some("resource.new"))
461 }
462
463 pub fn resource_rep(&mut self, ty: u32) -> u32 {
465 self.canonical_functions().resource_rep(ty);
466 self.core_funcs.add(Some("resource.rep"))
467 }
468
469 pub fn thread_spawn_ref(&mut self, ty: u32) -> u32 {
471 self.canonical_functions().thread_spawn_ref(ty);
472 self.core_funcs.add(Some("thread.spawn-ref"))
473 }
474
475 pub fn thread_available_parallelism(&mut self) -> u32 {
477 self.canonical_functions().thread_available_parallelism();
478 self.core_funcs.add(Some("thread.available-parallelism"))
479 }
480
481 pub fn backpressure_inc(&mut self) -> u32 {
483 self.canonical_functions().backpressure_inc();
484 self.core_funcs.add(Some("backpressure.inc"))
485 }
486
487 pub fn backpressure_dec(&mut self) -> u32 {
489 self.canonical_functions().backpressure_dec();
490 self.core_funcs.add(Some("backpressure.dec"))
491 }
492
493 pub fn task_return<O>(&mut self, ty: Option<ComponentValType>, options: O) -> u32
495 where
496 O: IntoIterator<Item = CanonicalOption>,
497 O::IntoIter: ExactSizeIterator,
498 {
499 self.canonical_functions().task_return(ty, options);
500 self.core_funcs.add(Some("task.return"))
501 }
502
503 pub fn task_cancel(&mut self) -> u32 {
505 self.canonical_functions().task_cancel();
506 self.core_funcs.add(Some("task.cancel"))
507 }
508
509 pub fn context_get(&mut self, ty: ValType, i: u32) -> u32 {
511 self.canonical_functions().context_get(ty, i);
512 self.core_funcs.add(Some(&format!("context.get {i}")))
513 }
514
515 pub fn context_set(&mut self, ty: ValType, i: u32) -> u32 {
517 self.canonical_functions().context_set(ty, i);
518 self.core_funcs.add(Some(&format!("context.set {i}")))
519 }
520
521 pub fn subtask_drop(&mut self) -> u32 {
523 self.canonical_functions().subtask_drop();
524 self.core_funcs.add(Some("subtask.drop"))
525 }
526
527 pub fn subtask_cancel(&mut self, async_: bool) -> u32 {
529 self.canonical_functions().subtask_cancel(async_);
530 self.core_funcs.add(Some("subtask.cancel"))
531 }
532
533 pub fn stream_new(&mut self, ty: u32) -> u32 {
535 self.canonical_functions().stream_new(ty);
536 self.core_funcs.add(Some("stream.new"))
537 }
538
539 pub fn stream_read<O>(&mut self, ty: u32, options: O) -> u32
541 where
542 O: IntoIterator<Item = CanonicalOption>,
543 O::IntoIter: ExactSizeIterator,
544 {
545 self.canonical_functions().stream_read(ty, options);
546 self.core_funcs.add(Some("stream.read"))
547 }
548
549 pub fn stream_write<O>(&mut self, ty: u32, options: O) -> u32
551 where
552 O: IntoIterator<Item = CanonicalOption>,
553 O::IntoIter: ExactSizeIterator,
554 {
555 self.canonical_functions().stream_write(ty, options);
556 self.core_funcs.add(Some("stream.write"))
557 }
558
559 pub fn stream_cancel_read(&mut self, ty: u32, async_: bool) -> u32 {
561 self.canonical_functions().stream_cancel_read(ty, async_);
562 self.core_funcs.add(Some("stream.cancel-read"))
563 }
564
565 pub fn stream_cancel_write(&mut self, ty: u32, async_: bool) -> u32 {
567 self.canonical_functions().stream_cancel_write(ty, async_);
568 self.core_funcs.add(Some("stream.cancel-write"))
569 }
570
571 pub fn stream_drop_readable(&mut self, ty: u32) -> u32 {
573 self.canonical_functions().stream_drop_readable(ty);
574 self.core_funcs.add(Some("stream.drop-readable"))
575 }
576
577 pub fn stream_drop_writable(&mut self, ty: u32) -> u32 {
579 self.canonical_functions().stream_drop_writable(ty);
580 self.core_funcs.add(Some("stream.drop-writable"))
581 }
582
583 pub fn future_new(&mut self, ty: u32) -> u32 {
585 self.canonical_functions().future_new(ty);
586 self.core_funcs.add(Some("future.new"))
587 }
588
589 pub fn future_read<O>(&mut self, ty: u32, options: O) -> u32
591 where
592 O: IntoIterator<Item = CanonicalOption>,
593 O::IntoIter: ExactSizeIterator,
594 {
595 self.canonical_functions().future_read(ty, options);
596 self.core_funcs.add(Some("future.read"))
597 }
598
599 pub fn future_write<O>(&mut self, ty: u32, options: O) -> u32
601 where
602 O: IntoIterator<Item = CanonicalOption>,
603 O::IntoIter: ExactSizeIterator,
604 {
605 self.canonical_functions().future_write(ty, options);
606 self.core_funcs.add(Some("future.write"))
607 }
608
609 pub fn future_cancel_read(&mut self, ty: u32, async_: bool) -> u32 {
611 self.canonical_functions().future_cancel_read(ty, async_);
612 self.core_funcs.add(Some("future.cancel-read"))
613 }
614
615 pub fn future_cancel_write(&mut self, ty: u32, async_: bool) -> u32 {
617 self.canonical_functions().future_cancel_write(ty, async_);
618 self.core_funcs.add(Some("future.cancel-write"))
619 }
620
621 pub fn future_drop_readable(&mut self, ty: u32) -> u32 {
623 self.canonical_functions().future_drop_readable(ty);
624 self.core_funcs.add(Some("future.drop-readable"))
625 }
626
627 pub fn future_drop_writable(&mut self, ty: u32) -> u32 {
629 self.canonical_functions().future_drop_writable(ty);
630 self.core_funcs.add(Some("future.drop-writable"))
631 }
632
633 pub fn error_context_new<O>(&mut self, options: O) -> u32
635 where
636 O: IntoIterator<Item = CanonicalOption>,
637 O::IntoIter: ExactSizeIterator,
638 {
639 self.canonical_functions().error_context_new(options);
640 self.core_funcs.add(Some("error-context.new"))
641 }
642
643 pub fn error_context_debug_message<O>(&mut self, options: O) -> u32
645 where
646 O: IntoIterator<Item = CanonicalOption>,
647 O::IntoIter: ExactSizeIterator,
648 {
649 self.canonical_functions()
650 .error_context_debug_message(options);
651 self.core_funcs.add(Some("error-context.debug-message"))
652 }
653
654 pub fn error_context_drop(&mut self) -> u32 {
656 self.canonical_functions().error_context_drop();
657 self.core_funcs.add(Some("error-context.drop"))
658 }
659
660 pub fn waitable_set_new(&mut self) -> u32 {
662 self.canonical_functions().waitable_set_new();
663 self.core_funcs.add(Some("waitable-set.new"))
664 }
665
666 pub fn waitable_set_wait(&mut self, cancellable: bool, memory: u32) -> u32 {
668 self.canonical_functions()
669 .waitable_set_wait(cancellable, memory);
670 self.core_funcs.add(Some("waitable-set.wait"))
671 }
672
673 pub fn waitable_set_poll(&mut self, cancellable: bool, memory: u32) -> u32 {
675 self.canonical_functions()
676 .waitable_set_poll(cancellable, memory);
677 self.core_funcs.add(Some("waitable-set.poll"))
678 }
679
680 pub fn waitable_set_drop(&mut self) -> u32 {
682 self.canonical_functions().waitable_set_drop();
683 self.core_funcs.add(Some("waitable-set.drop"))
684 }
685
686 pub fn waitable_join(&mut self) -> u32 {
688 self.canonical_functions().waitable_join();
689 self.core_funcs.add(Some("waitable.join"))
690 }
691
692 pub fn thread_index(&mut self) -> u32 {
694 self.canonical_functions().thread_index();
695 self.core_funcs.add(Some("thread.index"))
696 }
697
698 pub fn thread_new_indirect(&mut self, func_ty_idx: u32, table_index: u32) -> u32 {
700 self.canonical_functions()
701 .thread_new_indirect(func_ty_idx, table_index);
702 self.core_funcs.add(Some("thread.new-indirect"))
703 }
704
705 pub fn thread_resume_later(&mut self) -> u32 {
707 self.canonical_functions().thread_resume_later();
708 self.core_funcs.add(Some("thread.resume-later"))
709 }
710
711 pub fn thread_suspend(&mut self, cancellable: bool) -> u32 {
713 self.canonical_functions().thread_suspend(cancellable);
714 self.core_funcs.add(Some("thread.suspend"))
715 }
716
717 pub fn thread_yield(&mut self, cancellable: bool) -> u32 {
719 self.canonical_functions().thread_yield(cancellable);
720 self.core_funcs.add(Some("thread.yield"))
721 }
722
723 pub fn thread_suspend_then_resume(&mut self, cancellable: bool) -> u32 {
725 self.canonical_functions()
726 .thread_suspend_then_resume(cancellable);
727 self.core_funcs.add(Some("thread.suspend-then-resume"))
728 }
729
730 pub fn thread_yield_then_resume(&mut self, cancellable: bool) -> u32 {
732 self.canonical_functions()
733 .thread_yield_then_resume(cancellable);
734 self.core_funcs.add(Some("thread.yield-then-resume"))
735 }
736
737 pub fn thread_suspend_then_promote(&mut self, cancellable: bool) -> u32 {
739 self.canonical_functions()
740 .thread_suspend_then_promote(cancellable);
741 self.core_funcs.add(Some("thread.suspend-then-promote"))
742 }
743
744 pub fn thread_yield_then_promote(&mut self, cancellable: bool) -> u32 {
746 self.canonical_functions()
747 .thread_yield_then_promote(cancellable);
748 self.core_funcs.add(Some("thread.yield-then-resume"))
749 }
750
751 pub fn custom_section(&mut self, section: &CustomSection<'_>) {
753 self.flush();
754 self.component.section(section);
755 }
756
757 pub fn raw_custom_section(&mut self, section: &[u8]) {
759 self.flush();
760 self.component.section(&RawCustomSection(section));
761 }
762}
763
764macro_rules! section_accessors {
768 ($($method:ident => $section:ident)*) => (
769 #[derive(Debug, Default)]
770 enum LastSection {
771 #[default]
772 None,
773 $($section($section),)*
774 }
775
776 impl ComponentBuilder {
777 $(
778 fn $method(&mut self) -> &mut $section {
779 match &self.last_section {
780 LastSection::$section(_) => {}
783
784 _ => {
788 self.flush();
789 self.last_section = LastSection::$section($section::new());
790 }
791 }
792 match &mut self.last_section {
793 LastSection::$section(ret) => ret,
794 _ => unreachable!()
795 }
796 }
797 )*
798
799 fn flush(&mut self) {
802 match mem::take(&mut self.last_section) {
803 LastSection::None => {}
804 $(
805 LastSection::$section(section) => {
806 self.component.section(§ion);
807 }
808 )*
809 }
810 }
811
812 }
813 )
814}
815
816section_accessors! {
817 component_instances => ComponentInstanceSection
818 instances => InstanceSection
819 canonical_functions => CanonicalFunctionSection
820 aliases => ComponentAliasSection
821 exports => ComponentExportSection
822 imports => ComponentImportSection
823 types => ComponentTypeSection
824 core_types => CoreTypeSection
825}
826
827#[derive(Debug, Default)]
828struct Namespace {
829 count: u32,
830 names: NameMap,
831}
832
833impl Namespace {
834 fn add(&mut self, name: Option<&str>) -> u32 {
835 let ret = self.count;
836 self.count += 1;
837 if let Some(name) = name {
838 self.names.append(ret, name);
839 }
840 ret
841 }
842}