1 | use super::CORE_TYPE_SORT; |
2 | use crate::{ |
3 | encode_section, Alias, ComponentExportKind, ComponentOuterAliasKind, ComponentSection, |
4 | ComponentSectionId, ComponentTypeRef, CoreTypeEncoder, Encode, EntityType, ValType, |
5 | }; |
6 | use alloc::vec::Vec; |
7 | |
8 | /// Represents the type of a core module. |
9 | #[derive (Debug, Clone, Default)] |
10 | pub struct ModuleType { |
11 | bytes: Vec<u8>, |
12 | num_added: u32, |
13 | types_added: u32, |
14 | } |
15 | |
16 | impl 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 | |
73 | impl 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)] |
83 | pub struct ComponentCoreTypeEncoder<'a>(pub(crate) &'a mut Vec<u8>); |
84 | |
85 | impl<'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)] |
118 | pub struct CoreTypeSection { |
119 | bytes: Vec<u8>, |
120 | num_added: u32, |
121 | } |
122 | |
123 | impl 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 | |
149 | impl Encode for CoreTypeSection { |
150 | fn encode(&self, sink: &mut Vec<u8>) { |
151 | encode_section(sink, self.num_added, &self.bytes); |
152 | } |
153 | } |
154 | |
155 | impl 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)] |
163 | pub 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 | |
171 | impl 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 | |
272 | impl 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)] |
282 | pub struct InstanceType(ComponentType); |
283 | |
284 | impl 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 | |
345 | impl 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)] |
355 | pub struct ComponentFuncTypeEncoder<'a> { |
356 | params_encoded: bool, |
357 | results_encoded: bool, |
358 | sink: &'a mut Vec<u8>, |
359 | } |
360 | |
361 | impl<'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)] |
443 | pub struct ComponentTypeEncoder<'a>(&'a mut Vec<u8>); |
444 | |
445 | impl<'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)] |
485 | pub 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 | |
514 | impl 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)] |
536 | pub 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 | |
545 | impl 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 | |
554 | impl 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)] |
562 | pub struct ComponentDefinedTypeEncoder<'a>(&'a mut Vec<u8>); |
563 | |
564 | impl 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)] |
720 | pub struct ComponentTypeSection { |
721 | bytes: Vec<u8>, |
722 | num_added: u32, |
723 | } |
724 | |
725 | impl 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 | |
782 | impl Encode for ComponentTypeSection { |
783 | fn encode(&self, sink: &mut Vec<u8>) { |
784 | encode_section(sink, self.num_added, &self.bytes); |
785 | } |
786 | } |
787 | |
788 | impl ComponentSection for ComponentTypeSection { |
789 | fn id(&self) -> u8 { |
790 | ComponentSectionId::Type.into() |
791 | } |
792 | } |
793 | |