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_new(&mut self, ty: u32) -> u32 {
366 self.canonical_functions().resource_new(ty);
367 inc(&mut self.core_funcs)
368 }
369
370 pub fn resource_rep(&mut self, ty: u32) -> u32 {
372 self.canonical_functions().resource_rep(ty);
373 inc(&mut self.core_funcs)
374 }
375
376 pub fn thread_spawn(&mut self, ty: u32) -> u32 {
378 self.canonical_functions().thread_spawn(ty);
379 inc(&mut self.core_funcs)
380 }
381
382 pub fn thread_available_parallelism(&mut self) -> u32 {
384 self.canonical_functions().thread_available_parallelism();
385 inc(&mut self.core_funcs)
386 }
387
388 pub fn task_backpressure(&mut self) -> u32 {
390 self.canonical_functions().task_backpressure();
391 inc(&mut self.core_funcs)
392 }
393
394 pub fn task_return(&mut self, ty: Option<impl Into<ComponentValType>>) -> u32 {
396 self.canonical_functions().task_return(ty);
397 inc(&mut self.core_funcs)
398 }
399
400 pub fn task_wait(&mut self, async_: bool, memory: u32) -> u32 {
402 self.canonical_functions().task_wait(async_, memory);
403 inc(&mut self.core_funcs)
404 }
405
406 pub fn task_poll(&mut self, async_: bool, memory: u32) -> u32 {
408 self.canonical_functions().task_poll(async_, memory);
409 inc(&mut self.core_funcs)
410 }
411
412 pub fn task_yield(&mut self, async_: bool) -> u32 {
414 self.canonical_functions().task_yield(async_);
415 inc(&mut self.core_funcs)
416 }
417
418 pub fn subtask_drop(&mut self) -> u32 {
420 self.canonical_functions().subtask_drop();
421 inc(&mut self.core_funcs)
422 }
423
424 pub fn stream_new(&mut self, ty: u32) -> u32 {
426 self.canonical_functions().stream_new(ty);
427 inc(&mut self.core_funcs)
428 }
429
430 pub fn stream_read<O>(&mut self, ty: u32, options: O) -> u32
432 where
433 O: IntoIterator<Item = CanonicalOption>,
434 O::IntoIter: ExactSizeIterator,
435 {
436 self.canonical_functions().stream_read(ty, options);
437 inc(&mut self.core_funcs)
438 }
439
440 pub fn stream_write<O>(&mut self, ty: u32, options: O) -> u32
442 where
443 O: IntoIterator<Item = CanonicalOption>,
444 O::IntoIter: ExactSizeIterator,
445 {
446 self.canonical_functions().stream_write(ty, options);
447 inc(&mut self.core_funcs)
448 }
449
450 pub fn stream_cancel_read(&mut self, ty: u32, async_: bool) -> u32 {
452 self.canonical_functions().stream_cancel_read(ty, async_);
453 inc(&mut self.core_funcs)
454 }
455
456 pub fn stream_cancel_write(&mut self, ty: u32, async_: bool) -> u32 {
458 self.canonical_functions().stream_cancel_write(ty, async_);
459 inc(&mut self.core_funcs)
460 }
461
462 pub fn stream_close_readable(&mut self, ty: u32) -> u32 {
464 self.canonical_functions().stream_close_readable(ty);
465 inc(&mut self.core_funcs)
466 }
467
468 pub fn stream_close_writable(&mut self, ty: u32) -> u32 {
470 self.canonical_functions().stream_close_writable(ty);
471 inc(&mut self.core_funcs)
472 }
473
474 pub fn future_new(&mut self, ty: u32) -> u32 {
476 self.canonical_functions().future_new(ty);
477 inc(&mut self.core_funcs)
478 }
479
480 pub fn future_read<O>(&mut self, ty: u32, options: O) -> u32
482 where
483 O: IntoIterator<Item = CanonicalOption>,
484 O::IntoIter: ExactSizeIterator,
485 {
486 self.canonical_functions().future_read(ty, options);
487 inc(&mut self.core_funcs)
488 }
489
490 pub fn future_write<O>(&mut self, ty: u32, options: O) -> u32
492 where
493 O: IntoIterator<Item = CanonicalOption>,
494 O::IntoIter: ExactSizeIterator,
495 {
496 self.canonical_functions().future_write(ty, options);
497 inc(&mut self.core_funcs)
498 }
499
500 pub fn future_cancel_read(&mut self, ty: u32, async_: bool) -> u32 {
502 self.canonical_functions().future_cancel_read(ty, async_);
503 inc(&mut self.core_funcs)
504 }
505
506 pub fn future_cancel_write(&mut self, ty: u32, async_: bool) -> u32 {
508 self.canonical_functions().future_cancel_write(ty, async_);
509 inc(&mut self.core_funcs)
510 }
511
512 pub fn future_close_readable(&mut self, ty: u32) -> u32 {
514 self.canonical_functions().future_close_readable(ty);
515 inc(&mut self.core_funcs)
516 }
517
518 pub fn future_close_writable(&mut self, ty: u32) -> u32 {
520 self.canonical_functions().future_close_writable(ty);
521 inc(&mut self.core_funcs)
522 }
523
524 pub fn error_context_new<O>(&mut self, options: O) -> u32
526 where
527 O: IntoIterator<Item = CanonicalOption>,
528 O::IntoIter: ExactSizeIterator,
529 {
530 self.canonical_functions().error_context_new(options);
531 inc(&mut self.core_funcs)
532 }
533
534 pub fn error_context_debug_message<O>(&mut self, options: O) -> u32
536 where
537 O: IntoIterator<Item = CanonicalOption>,
538 O::IntoIter: ExactSizeIterator,
539 {
540 self.canonical_functions()
541 .error_context_debug_message(options);
542 inc(&mut self.core_funcs)
543 }
544
545 pub fn error_context_drop(&mut self) -> u32 {
547 self.canonical_functions().error_context_drop();
548 inc(&mut self.core_funcs)
549 }
550
551 pub fn custom_section(&mut self, section: &CustomSection<'_>) {
553 self.flush();
554 self.component.section(section);
555 }
556
557 pub fn raw_custom_section(&mut self, section: &[u8]) {
559 self.flush();
560 self.component.section(&RawCustomSection(section));
561 }
562}
563
564macro_rules! section_accessors {
568 ($($method:ident => $section:ident)*) => (
569 #[derive(Debug, Default)]
570 enum LastSection {
571 #[default]
572 None,
573 $($section($section),)*
574 }
575
576 impl ComponentBuilder {
577 $(
578 fn $method(&mut self) -> &mut $section {
579 match &self.last_section {
580 LastSection::$section(_) => {}
583
584 _ => {
588 self.flush();
589 self.last_section = LastSection::$section($section::new());
590 }
591 }
592 match &mut self.last_section {
593 LastSection::$section(ret) => ret,
594 _ => unreachable!()
595 }
596 }
597 )*
598
599 fn flush(&mut self) {
602 match mem::take(&mut self.last_section) {
603 LastSection::None => {}
604 $(
605 LastSection::$section(section) => {
606 self.component.section(§ion);
607 }
608 )*
609 }
610 }
611
612 }
613 )
614}
615
616section_accessors! {
617 component_instances => ComponentInstanceSection
618 instances => InstanceSection
619 canonical_functions => CanonicalFunctionSection
620 aliases => ComponentAliasSection
621 exports => ComponentExportSection
622 imports => ComponentImportSection
623 types => ComponentTypeSection
624 core_types => CoreTypeSection
625}
626
627fn inc(idx: &mut u32) -> u32 {
628 let ret = *idx;
629 *idx += 1;
630 ret
631}