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