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(&mut self, name: &str, ty: ComponentTypeRef) -> u32 {
331 let ret = match &ty {
332 ComponentTypeRef::Instance(_) => self.instances.add(Some(name)),
333 ComponentTypeRef::Func(_) => self.funcs.add(Some(name)),
334 ComponentTypeRef::Type(..) => self.types.add(Some(name)),
335 ComponentTypeRef::Component(_) => self.components.add(Some(name)),
336 ComponentTypeRef::Module(_) => self.core_modules.add(Some(name)),
337 ComponentTypeRef::Value(_) => self.values.add(Some(name)),
338 };
339 self.imports().import(name, ty);
340 ret
341 }
342
343 pub fn export(
349 &mut self,
350 name: &str,
351 kind: ComponentExportKind,
352 idx: u32,
353 ty: Option<ComponentTypeRef>,
354 ) -> u32 {
355 self.exports().export(name, kind, idx, ty);
356 self.inc_kind(Some(name), kind)
357 }
358
359 pub fn core_type(&mut self, debug_name: Option<&str>) -> (u32, ComponentCoreTypeEncoder<'_>) {
361 (self.core_types.add(debug_name), self.core_types().ty())
362 }
363
364 pub fn ty(&mut self, debug_name: Option<&str>) -> (u32, ComponentTypeEncoder<'_>) {
366 (self.types.add(debug_name), self.types().ty())
367 }
368
369 pub fn type_instance(&mut self, debug_name: Option<&str>, ty: &InstanceType) -> u32 {
371 self.types().instance(ty);
372 self.types.add(debug_name)
373 }
374
375 pub fn type_component(&mut self, debug_name: Option<&str>, ty: &ComponentType) -> u32 {
377 self.types().component(ty);
378 self.types.add(debug_name)
379 }
380
381 pub fn type_defined(
383 &mut self,
384 debug_name: Option<&str>,
385 ) -> (u32, ComponentDefinedTypeEncoder<'_>) {
386 (self.types.add(debug_name), self.types().defined_type())
387 }
388
389 pub fn type_function(
391 &mut self,
392 debug_name: Option<&str>,
393 ) -> (u32, ComponentFuncTypeEncoder<'_>) {
394 (self.types.add(debug_name), self.types().function())
395 }
396
397 pub fn type_resource(
399 &mut self,
400 debug_name: Option<&str>,
401 rep: ValType,
402 dtor: Option<u32>,
403 ) -> u32 {
404 self.types().resource(rep, dtor);
405 self.types.add(debug_name)
406 }
407
408 pub fn component(&mut self, debug_name: Option<&str>, mut builder: ComponentBuilder) -> u32 {
410 builder.flush();
411 self.flush();
412 self.component
413 .section(&NestedComponentSection(&builder.component));
414 self.components.add(debug_name)
415 }
416
417 pub fn component_raw(&mut self, debug_name: Option<&str>, data: &[u8]) -> u32 {
419 let raw_section = RawSection {
420 id: ComponentSectionId::Component.into(),
421 data,
422 };
423 self.flush();
424 self.component.section(&raw_section);
425 self.components.add(debug_name)
426 }
427
428 pub fn instantiate<A, S>(
430 &mut self,
431 debug_name: Option<&str>,
432 component_index: u32,
433 args: A,
434 ) -> u32
435 where
436 A: IntoIterator<Item = (S, ComponentExportKind, u32)>,
437 A::IntoIter: ExactSizeIterator,
438 S: AsRef<str>,
439 {
440 self.component_instances()
441 .instantiate(component_index, args);
442 self.instances.add(debug_name)
443 }
444
445 pub fn resource_drop(&mut self, ty: u32) -> u32 {
447 self.canonical_functions().resource_drop(ty);
448 self.core_funcs.add(Some("resource.drop"))
449 }
450
451 pub fn resource_drop_async(&mut self, ty: u32) -> u32 {
453 self.canonical_functions().resource_drop_async(ty);
454 self.core_funcs.add(Some("resource.drop async"))
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_set(&mut self) -> u32 {
483 self.canonical_functions().backpressure_set();
484 self.core_funcs.add(Some("backpressure.set"))
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, i: u32) -> u32 {
517 self.canonical_functions().context_get(i);
518 self.core_funcs.add(Some(&format!("context.get {i}")))
519 }
520
521 pub fn context_set(&mut self, i: u32) -> u32 {
523 self.canonical_functions().context_set(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_switch_to(&mut self, cancellable: bool) -> u32 {
719 self.canonical_functions().thread_switch_to(cancellable);
720 self.core_funcs.add(Some("thread.switch-to"))
721 }
722
723 pub fn thread_suspend(&mut self, cancellable: bool) -> u32 {
725 self.canonical_functions().thread_suspend(cancellable);
726 self.core_funcs.add(Some("thread.suspend"))
727 }
728
729 pub fn thread_resume_later(&mut self) -> u32 {
731 self.canonical_functions().thread_resume_later();
732 self.core_funcs.add(Some("thread.resume-later"))
733 }
734
735 pub fn thread_yield_to(&mut self, cancellable: bool) -> u32 {
737 self.canonical_functions().thread_yield_to(cancellable);
738 self.core_funcs.add(Some("thread.yield-to"))
739 }
740
741 pub fn custom_section(&mut self, section: &CustomSection<'_>) {
743 self.flush();
744 self.component.section(section);
745 }
746
747 pub fn raw_custom_section(&mut self, section: &[u8]) {
749 self.flush();
750 self.component.section(&RawCustomSection(section));
751 }
752}
753
754macro_rules! section_accessors {
758 ($($method:ident => $section:ident)*) => (
759 #[derive(Debug, Default)]
760 enum LastSection {
761 #[default]
762 None,
763 $($section($section),)*
764 }
765
766 impl ComponentBuilder {
767 $(
768 fn $method(&mut self) -> &mut $section {
769 match &self.last_section {
770 LastSection::$section(_) => {}
773
774 _ => {
778 self.flush();
779 self.last_section = LastSection::$section($section::new());
780 }
781 }
782 match &mut self.last_section {
783 LastSection::$section(ret) => ret,
784 _ => unreachable!()
785 }
786 }
787 )*
788
789 fn flush(&mut self) {
792 match mem::take(&mut self.last_section) {
793 LastSection::None => {}
794 $(
795 LastSection::$section(section) => {
796 self.component.section(§ion);
797 }
798 )*
799 }
800 }
801
802 }
803 )
804}
805
806section_accessors! {
807 component_instances => ComponentInstanceSection
808 instances => InstanceSection
809 canonical_functions => CanonicalFunctionSection
810 aliases => ComponentAliasSection
811 exports => ComponentExportSection
812 imports => ComponentImportSection
813 types => ComponentTypeSection
814 core_types => CoreTypeSection
815}
816
817#[derive(Debug, Default)]
818struct Namespace {
819 count: u32,
820 names: NameMap,
821}
822
823impl Namespace {
824 fn add(&mut self, name: Option<&str>) -> u32 {
825 let ret = self.count;
826 self.count += 1;
827 if let Some(name) = name {
828 self.names.append(ret, name);
829 }
830 ret
831 }
832}