1use super::CORE_TYPE_SORT;
2use crate::{
3 encode_section, Alias, ComponentExportKind, ComponentOuterAliasKind, ComponentSection,
4 ComponentSectionId, ComponentTypeRef, CoreTypeEncoder, Encode, EntityType, ValType,
5};
6use alloc::vec::Vec;
7
8/// Represents the type of a core module.
9#[derive(Debug, Clone, Default)]
10pub struct ModuleType {
11 bytes: Vec<u8>,
12 num_added: u32,
13 types_added: u32,
14}
15
16impl ModuleType {
17 /// Creates a new core module type.
18 pub fn new() -> Self {
19 Self::default()
20 }
21
22 /// Defines an import in this module type.
23 pub fn import(&mut self, module: &str, name: &str, ty: EntityType) -> &mut Self {
24 self.bytes.push(0x00);
25 module.encode(&mut self.bytes);
26 name.encode(&mut self.bytes);
27 ty.encode(&mut self.bytes);
28 self.num_added += 1;
29 self
30 }
31
32 /// Define a type in this module type.
33 ///
34 /// The returned encoder must be used before adding another definition.
35 #[must_use = "the encoder must be used to encode the type"]
36 pub fn ty(&mut self) -> CoreTypeEncoder {
37 self.bytes.push(0x01);
38 self.num_added += 1;
39 self.types_added += 1;
40 CoreTypeEncoder {
41 push_prefix_if_component_core_type: false,
42 bytes: &mut self.bytes,
43 }
44 }
45
46 /// Defines an outer core type alias in this module type.
47 pub fn alias_outer_core_type(&mut self, count: u32, index: u32) -> &mut Self {
48 self.bytes.push(0x02);
49 self.bytes.push(CORE_TYPE_SORT);
50 self.bytes.push(0x01); // outer
51 count.encode(&mut self.bytes);
52 index.encode(&mut self.bytes);
53 self.num_added += 1;
54 self.types_added += 1;
55 self
56 }
57
58 /// Defines an export in this module type.
59 pub fn export(&mut self, name: &str, ty: EntityType) -> &mut Self {
60 self.bytes.push(0x03);
61 name.encode(&mut self.bytes);
62 ty.encode(&mut self.bytes);
63 self.num_added += 1;
64 self
65 }
66
67 /// Gets the number of types that have been added to this module type.
68 pub fn type_count(&self) -> u32 {
69 self.types_added
70 }
71}
72
73impl Encode for ModuleType {
74 fn encode(&self, sink: &mut Vec<u8>) {
75 sink.push(0x50);
76 self.num_added.encode(sink);
77 sink.extend(&self.bytes);
78 }
79}
80
81/// Used to encode core types.
82#[derive(Debug)]
83pub struct ComponentCoreTypeEncoder<'a>(pub(crate) &'a mut Vec<u8>);
84
85impl<'a> ComponentCoreTypeEncoder<'a> {
86 /// Define a module type.
87 pub fn module(self, ty: &ModuleType) {
88 ty.encode(self.0);
89 }
90
91 /// Define any core type other than a module type.
92 #[must_use = "the encoder must be used to encode the type"]
93 pub fn core(self) -> CoreTypeEncoder<'a> {
94 CoreTypeEncoder {
95 bytes: self.0,
96 push_prefix_if_component_core_type: true,
97 }
98 }
99}
100
101/// An encoder for the core type section of WebAssembly components.
102///
103/// # Example
104///
105/// ```rust
106/// use wasm_encoder::{Component, CoreTypeSection, ModuleType};
107///
108/// let mut types = CoreTypeSection::new();
109///
110/// types.ty().module(&ModuleType::new());
111///
112/// let mut component = Component::new();
113/// component.section(&types);
114///
115/// let bytes = component.finish();
116/// ```
117#[derive(Clone, Debug, Default)]
118pub struct CoreTypeSection {
119 bytes: Vec<u8>,
120 num_added: u32,
121}
122
123impl CoreTypeSection {
124 /// Create a new core type section encoder.
125 pub fn new() -> Self {
126 Self::default()
127 }
128
129 /// The number of types in the section.
130 pub fn len(&self) -> u32 {
131 self.num_added
132 }
133
134 /// Determines if the section is empty.
135 pub fn is_empty(&self) -> bool {
136 self.num_added == 0
137 }
138
139 /// Encode a type into this section.
140 ///
141 /// The returned encoder must be finished before adding another type.
142 #[must_use = "the encoder must be used to encode the type"]
143 pub fn ty(&mut self) -> ComponentCoreTypeEncoder<'_> {
144 self.num_added += 1;
145 ComponentCoreTypeEncoder(&mut self.bytes)
146 }
147}
148
149impl Encode for CoreTypeSection {
150 fn encode(&self, sink: &mut Vec<u8>) {
151 encode_section(sink, self.num_added, &self.bytes);
152 }
153}
154
155impl ComponentSection for CoreTypeSection {
156 fn id(&self) -> u8 {
157 ComponentSectionId::CoreType.into()
158 }
159}
160
161/// Represents a component type.
162#[derive(Debug, Clone, Default)]
163pub struct ComponentType {
164 bytes: Vec<u8>,
165 num_added: u32,
166 core_types_added: u32,
167 types_added: u32,
168 instances_added: u32,
169}
170
171impl ComponentType {
172 /// Creates a new component type.
173 pub fn new() -> Self {
174 Self::default()
175 }
176
177 /// Define a core type in this component type.
178 ///
179 /// The returned encoder must be used before adding another definition.
180 #[must_use = "the encoder must be used to encode the type"]
181 pub fn core_type(&mut self) -> ComponentCoreTypeEncoder {
182 self.bytes.push(0x00);
183 self.num_added += 1;
184 self.core_types_added += 1;
185 ComponentCoreTypeEncoder(&mut self.bytes)
186 }
187
188 /// Define a type in this component type.
189 ///
190 /// The returned encoder must be used before adding another definition.
191 #[must_use = "the encoder must be used to encode the type"]
192 pub fn ty(&mut self) -> ComponentTypeEncoder {
193 self.bytes.push(0x01);
194 self.num_added += 1;
195 self.types_added += 1;
196 ComponentTypeEncoder(&mut self.bytes)
197 }
198
199 /// Defines an alias for an exported item of a prior instance or an
200 /// outer type.
201 pub fn alias(&mut self, alias: Alias<'_>) -> &mut Self {
202 self.bytes.push(0x02);
203 alias.encode(&mut self.bytes);
204 self.num_added += 1;
205 match &alias {
206 Alias::InstanceExport {
207 kind: ComponentExportKind::Type,
208 ..
209 }
210 | Alias::Outer {
211 kind: ComponentOuterAliasKind::Type,
212 ..
213 } => self.types_added += 1,
214 Alias::Outer {
215 kind: ComponentOuterAliasKind::CoreType,
216 ..
217 } => self.core_types_added += 1,
218 Alias::InstanceExport {
219 kind: ComponentExportKind::Instance,
220 ..
221 } => self.instances_added += 1,
222 _ => {}
223 }
224 self
225 }
226
227 /// Defines an import in this component type.
228 pub fn import(&mut self, name: &str, ty: ComponentTypeRef) -> &mut Self {
229 self.bytes.push(0x03);
230 crate::encode_component_import_name(&mut self.bytes, name);
231 ty.encode(&mut self.bytes);
232 self.num_added += 1;
233 match ty {
234 ComponentTypeRef::Type(..) => self.types_added += 1,
235 ComponentTypeRef::Instance(..) => self.instances_added += 1,
236 _ => {}
237 }
238 self
239 }
240
241 /// Defines an export in this component type.
242 pub fn export(&mut self, name: &str, ty: ComponentTypeRef) -> &mut Self {
243 self.bytes.push(0x04);
244 crate::encode_component_export_name(&mut self.bytes, name);
245 ty.encode(&mut self.bytes);
246 self.num_added += 1;
247 match ty {
248 ComponentTypeRef::Type(..) => self.types_added += 1,
249 ComponentTypeRef::Instance(..) => self.instances_added += 1,
250 _ => {}
251 }
252 self
253 }
254
255 /// Gets the number of core types that have been added to this component type.
256 pub fn core_type_count(&self) -> u32 {
257 self.core_types_added
258 }
259
260 /// Gets the number of types that have been added or aliased in this component type.
261 pub fn type_count(&self) -> u32 {
262 self.types_added
263 }
264
265 /// Gets the number of instances that have been defined in this component
266 /// type through imports, exports, or aliases.
267 pub fn instance_count(&self) -> u32 {
268 self.instances_added
269 }
270}
271
272impl Encode for ComponentType {
273 fn encode(&self, sink: &mut Vec<u8>) {
274 sink.push(0x41);
275 self.num_added.encode(sink);
276 sink.extend(&self.bytes);
277 }
278}
279
280/// Represents an instance type.
281#[derive(Debug, Clone, Default)]
282pub struct InstanceType(ComponentType);
283
284impl InstanceType {
285 /// Creates a new instance type.
286 pub fn new() -> Self {
287 Self::default()
288 }
289
290 /// Define a core type in this instance type.
291 ///
292 /// The returned encoder must be used before adding another definition.
293 #[must_use = "the encoder must be used to encode the type"]
294 pub fn core_type(&mut self) -> ComponentCoreTypeEncoder {
295 self.0.core_type()
296 }
297
298 /// Define a type in this instance type.
299 ///
300 /// The returned encoder must be used before adding another definition.
301 #[must_use = "the encoder must be used to encode the type"]
302 pub fn ty(&mut self) -> ComponentTypeEncoder {
303 self.0.ty()
304 }
305
306 /// Defines an outer core type alias in this component type.
307 pub fn alias(&mut self, alias: Alias<'_>) -> &mut Self {
308 self.0.alias(alias);
309 self
310 }
311
312 /// Defines an export in this instance type.
313 pub fn export(&mut self, name: &str, ty: ComponentTypeRef) -> &mut Self {
314 self.0.export(name, ty);
315 self
316 }
317
318 /// Gets the number of core types that have been added to this instance type.
319 pub fn core_type_count(&self) -> u32 {
320 self.0.core_types_added
321 }
322
323 /// Gets the number of types that have been added or aliased in this instance type.
324 pub fn type_count(&self) -> u32 {
325 self.0.types_added
326 }
327
328 /// Gets the number of instances that have been imported or exported or
329 /// aliased in this instance type.
330 pub fn instance_count(&self) -> u32 {
331 self.0.instances_added
332 }
333
334 /// Returns whether or not this instance type is empty.
335 pub fn is_empty(&self) -> bool {
336 self.0.num_added == 0
337 }
338
339 /// Returns the number of entries added to this instance types.
340 pub fn len(&self) -> u32 {
341 self.0.num_added
342 }
343}
344
345impl Encode for InstanceType {
346 fn encode(&self, sink: &mut Vec<u8>) {
347 sink.push(0x42);
348 self.0.num_added.encode(sink);
349 sink.extend(&self.0.bytes);
350 }
351}
352
353/// Used to encode component function types.
354#[derive(Debug)]
355pub struct ComponentFuncTypeEncoder<'a> {
356 params_encoded: bool,
357 results_encoded: bool,
358 sink: &'a mut Vec<u8>,
359}
360
361impl<'a> ComponentFuncTypeEncoder<'a> {
362 fn new(sink: &'a mut Vec<u8>) -> Self {
363 sink.push(0x40);
364 Self {
365 params_encoded: false,
366 results_encoded: false,
367 sink,
368 }
369 }
370
371 /// Defines named parameters.
372 ///
373 /// Parameters must be defined before defining results.
374 ///
375 /// # Panics
376 ///
377 /// This method will panic if the function is called twice since parameters
378 /// can only be encoded once.
379 pub fn params<'b, P, T>(&mut self, params: P) -> &mut Self
380 where
381 P: IntoIterator<Item = (&'b str, T)>,
382 P::IntoIter: ExactSizeIterator,
383 T: Into<ComponentValType>,
384 {
385 assert!(!self.params_encoded);
386 self.params_encoded = true;
387 let params = params.into_iter();
388 params.len().encode(self.sink);
389 for (name, ty) in params {
390 name.encode(self.sink);
391 ty.into().encode(self.sink);
392 }
393 self
394 }
395
396 /// Defines a single unnamed result.
397 ///
398 /// This method cannot be used with `results`.
399 ///
400 /// # Panics
401 ///
402 /// This method will panic if the function is called twice, called before
403 /// the `params` method, or called in addition to the `results` method.
404 pub fn result(&mut self, ty: impl Into<ComponentValType>) -> &mut Self {
405 assert!(self.params_encoded);
406 assert!(!self.results_encoded);
407 self.results_encoded = true;
408 self.sink.push(0x00);
409 ty.into().encode(self.sink);
410 self
411 }
412
413 /// Defines named results.
414 ///
415 /// This method cannot be used with `result`.
416 ///
417 /// # Panics
418 ///
419 /// This method will panic if the function is called twice, called before
420 /// the `params` method, or called in addition to the `result` method.
421 pub fn results<'b, R, T>(&mut self, results: R) -> &mut Self
422 where
423 R: IntoIterator<Item = (&'b str, T)>,
424 R::IntoIter: ExactSizeIterator,
425 T: Into<ComponentValType>,
426 {
427 assert!(self.params_encoded);
428 assert!(!self.results_encoded);
429 self.results_encoded = true;
430 self.sink.push(0x01);
431 let results = results.into_iter();
432 results.len().encode(self.sink);
433 for (name, ty) in results {
434 name.encode(self.sink);
435 ty.into().encode(self.sink);
436 }
437 self
438 }
439}
440
441/// Used to encode component and instance types.
442#[derive(Debug)]
443pub struct ComponentTypeEncoder<'a>(&'a mut Vec<u8>);
444
445impl<'a> ComponentTypeEncoder<'a> {
446 /// Define a component type.
447 pub fn component(self, ty: &ComponentType) {
448 ty.encode(self.0);
449 }
450
451 /// Define an instance type.
452 pub fn instance(self, ty: &InstanceType) {
453 ty.encode(self.0);
454 }
455
456 /// Define a function type.
457 pub fn function(self) -> ComponentFuncTypeEncoder<'a> {
458 ComponentFuncTypeEncoder::new(self.0)
459 }
460
461 /// Define a defined component type.
462 ///
463 /// The returned encoder must be used before adding another type.
464 #[must_use = "the encoder must be used to encode the type"]
465 pub fn defined_type(self) -> ComponentDefinedTypeEncoder<'a> {
466 ComponentDefinedTypeEncoder(self.0)
467 }
468
469 /// Define a resource type.
470 pub fn resource(self, rep: ValType, dtor: Option<u32>) {
471 self.0.push(0x3f);
472 rep.encode(self.0);
473 match dtor {
474 Some(i) => {
475 self.0.push(0x01);
476 i.encode(self.0);
477 }
478 None => self.0.push(0x00),
479 }
480 }
481}
482
483/// Represents a primitive component value type.
484#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
485pub enum PrimitiveValType {
486 /// The type is a boolean.
487 Bool,
488 /// The type is a signed 8-bit integer.
489 S8,
490 /// The type is an unsigned 8-bit integer.
491 U8,
492 /// The type is a signed 16-bit integer.
493 S16,
494 /// The type is an unsigned 16-bit integer.
495 U16,
496 /// The type is a signed 32-bit integer.
497 S32,
498 /// The type is an unsigned 32-bit integer.
499 U32,
500 /// The type is a signed 64-bit integer.
501 S64,
502 /// The type is an unsigned 64-bit integer.
503 U64,
504 /// The type is a 32-bit floating point number with only one NaN.
505 F32,
506 /// The type is a 64-bit floating point number with only one NaN.
507 F64,
508 /// The type is a Unicode character.
509 Char,
510 /// The type is a string.
511 String,
512}
513
514impl Encode for PrimitiveValType {
515 fn encode(&self, sink: &mut Vec<u8>) {
516 sink.push(match self {
517 Self::Bool => 0x7f,
518 Self::S8 => 0x7e,
519 Self::U8 => 0x7d,
520 Self::S16 => 0x7c,
521 Self::U16 => 0x7b,
522 Self::S32 => 0x7a,
523 Self::U32 => 0x79,
524 Self::S64 => 0x78,
525 Self::U64 => 0x77,
526 Self::F32 => 0x76,
527 Self::F64 => 0x75,
528 Self::Char => 0x74,
529 Self::String => 0x73,
530 });
531 }
532}
533
534/// Represents a component value type.
535#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
536pub enum ComponentValType {
537 /// The value is a primitive type.
538 Primitive(PrimitiveValType),
539 /// The value is to a defined value type.
540 ///
541 /// The type index must be to a value type.
542 Type(u32),
543}
544
545impl Encode for ComponentValType {
546 fn encode(&self, sink: &mut Vec<u8>) {
547 match self {
548 Self::Primitive(ty: &PrimitiveValType) => ty.encode(sink),
549 Self::Type(index: &u32) => (*index as i64).encode(sink),
550 }
551 }
552}
553
554impl From<PrimitiveValType> for ComponentValType {
555 fn from(ty: PrimitiveValType) -> Self {
556 Self::Primitive(ty)
557 }
558}
559
560/// Used for encoding component defined types.
561#[derive(Debug)]
562pub struct ComponentDefinedTypeEncoder<'a>(&'a mut Vec<u8>);
563
564impl ComponentDefinedTypeEncoder<'_> {
565 /// Define a primitive value type.
566 pub fn primitive(self, ty: PrimitiveValType) {
567 ty.encode(self.0);
568 }
569
570 /// Define a record type.
571 pub fn record<'a, F, T>(self, fields: F)
572 where
573 F: IntoIterator<Item = (&'a str, T)>,
574 F::IntoIter: ExactSizeIterator,
575 T: Into<ComponentValType>,
576 {
577 let fields = fields.into_iter();
578 self.0.push(0x72);
579 fields.len().encode(self.0);
580 for (name, ty) in fields {
581 name.encode(self.0);
582 ty.into().encode(self.0);
583 }
584 }
585
586 /// Define a variant type.
587 pub fn variant<'a, C>(self, cases: C)
588 where
589 C: IntoIterator<Item = (&'a str, Option<ComponentValType>, Option<u32>)>,
590 C::IntoIter: ExactSizeIterator,
591 {
592 let cases = cases.into_iter();
593 self.0.push(0x71);
594 cases.len().encode(self.0);
595 for (name, ty, refines) in cases {
596 name.encode(self.0);
597 ty.encode(self.0);
598 refines.encode(self.0);
599 }
600 }
601
602 /// Define a list type.
603 pub fn list(self, ty: impl Into<ComponentValType>) {
604 self.0.push(0x70);
605 ty.into().encode(self.0);
606 }
607
608 /// Define a tuple type.
609 pub fn tuple<I, T>(self, types: I)
610 where
611 I: IntoIterator<Item = T>,
612 I::IntoIter: ExactSizeIterator,
613 T: Into<ComponentValType>,
614 {
615 let types = types.into_iter();
616 self.0.push(0x6F);
617 types.len().encode(self.0);
618 for ty in types {
619 ty.into().encode(self.0);
620 }
621 }
622
623 /// Define a flags type.
624 pub fn flags<'a, I>(self, names: I)
625 where
626 I: IntoIterator<Item = &'a str>,
627 I::IntoIter: ExactSizeIterator,
628 {
629 let names = names.into_iter();
630 self.0.push(0x6E);
631 names.len().encode(self.0);
632 for name in names {
633 name.encode(self.0);
634 }
635 }
636
637 /// Define an enum type.
638 pub fn enum_type<'a, I>(self, tags: I)
639 where
640 I: IntoIterator<Item = &'a str>,
641 I::IntoIter: ExactSizeIterator,
642 {
643 let tags = tags.into_iter();
644 self.0.push(0x6D);
645 tags.len().encode(self.0);
646 for tag in tags {
647 tag.encode(self.0);
648 }
649 }
650
651 /// Define an option type.
652 pub fn option(self, ty: impl Into<ComponentValType>) {
653 self.0.push(0x6B);
654 ty.into().encode(self.0);
655 }
656
657 /// Define a result type.
658 pub fn result(self, ok: Option<ComponentValType>, err: Option<ComponentValType>) {
659 self.0.push(0x6A);
660 ok.encode(self.0);
661 err.encode(self.0);
662 }
663
664 /// Define a `own` handle type
665 pub fn own(self, idx: u32) {
666 self.0.push(0x69);
667 idx.encode(self.0);
668 }
669
670 /// Define a `borrow` handle type
671 pub fn borrow(self, idx: u32) {
672 self.0.push(0x68);
673 idx.encode(self.0);
674 }
675
676 /// Define a `future` type with the specified payload.
677 pub fn future(self, payload: Option<ComponentValType>) {
678 self.0.push(0x67);
679 payload.encode(self.0);
680 }
681
682 /// Define a `stream` type with the specified payload.
683 pub fn stream(self, payload: ComponentValType) {
684 self.0.push(0x66);
685 payload.encode(self.0);
686 }
687
688 /// Define the `error-context` type.
689 pub fn error_context(self) {
690 self.0.push(0x65);
691 }
692}
693
694/// An encoder for the type section of WebAssembly components.
695///
696/// # Example
697///
698/// ```rust
699/// use wasm_encoder::{Component, ComponentTypeSection, PrimitiveValType};
700///
701/// let mut types = ComponentTypeSection::new();
702///
703/// // Define a function type of `[string, string] -> string`.
704/// types
705/// .function()
706/// .params(
707/// [
708/// ("a", PrimitiveValType::String),
709/// ("b", PrimitiveValType::String)
710/// ]
711/// )
712/// .result(PrimitiveValType::String);
713///
714/// let mut component = Component::new();
715/// component.section(&types);
716///
717/// let bytes = component.finish();
718/// ```
719#[derive(Clone, Debug, Default)]
720pub struct ComponentTypeSection {
721 bytes: Vec<u8>,
722 num_added: u32,
723}
724
725impl ComponentTypeSection {
726 /// Create a new component type section encoder.
727 pub fn new() -> Self {
728 Self::default()
729 }
730
731 /// The number of types in the section.
732 pub fn len(&self) -> u32 {
733 self.num_added
734 }
735
736 /// Determines if the section is empty.
737 pub fn is_empty(&self) -> bool {
738 self.num_added == 0
739 }
740
741 /// Encode a type into this section.
742 ///
743 /// The returned encoder must be finished before adding another type.
744 #[must_use = "the encoder must be used to encode the type"]
745 pub fn ty(&mut self) -> ComponentTypeEncoder<'_> {
746 self.num_added += 1;
747 ComponentTypeEncoder(&mut self.bytes)
748 }
749
750 /// Define a component type in this type section.
751 pub fn component(&mut self, ty: &ComponentType) -> &mut Self {
752 self.ty().component(ty);
753 self
754 }
755
756 /// Define an instance type in this type section.
757 pub fn instance(&mut self, ty: &InstanceType) -> &mut Self {
758 self.ty().instance(ty);
759 self
760 }
761
762 /// Define a function type in this type section.
763 pub fn function(&mut self) -> ComponentFuncTypeEncoder<'_> {
764 self.ty().function()
765 }
766
767 /// Add a component defined type to this type section.
768 ///
769 /// The returned encoder must be used before adding another type.
770 #[must_use = "the encoder must be used to encode the type"]
771 pub fn defined_type(&mut self) -> ComponentDefinedTypeEncoder<'_> {
772 self.ty().defined_type()
773 }
774
775 /// Defines a new resource type.
776 pub fn resource(&mut self, rep: ValType, dtor: Option<u32>) -> &mut Self {
777 self.ty().resource(rep, dtor);
778 self
779 }
780}
781
782impl Encode for ComponentTypeSection {
783 fn encode(&self, sink: &mut Vec<u8>) {
784 encode_section(sink, self.num_added, &self.bytes);
785 }
786}
787
788impl ComponentSection for ComponentTypeSection {
789 fn id(&self) -> u8 {
790 ComponentSectionId::Type.into()
791 }
792}
793