1use crate::{
2 validation::{expected_export_name, validate_module},
3 StringEncoding,
4};
5use anyhow::{anyhow, bail, Context, Result};
6use indexmap::{map::Entry, IndexMap, IndexSet};
7use std::{
8 hash::{Hash, Hasher},
9 ops::{BitOr, BitOrAssign},
10};
11use wasm_encoder::*;
12use wasmparser::{Validator, WasmFeatures};
13use wasmer_wit_parser::{
14 abi::{AbiVariant, WasmSignature, WasmType},
15 Enum, Expected, Flags, Function, FunctionKind, Interface, Record, Tuple, Type, TypeDef,
16 TypeDefKind, Union, Variant,
17};
18
19const INDIRECT_TABLE_NAME: &str = "$imports";
20
21fn to_val_type(ty: &WasmType) -> ValType {
22 match ty {
23 WasmType::I32 => ValType::I32,
24 WasmType::I64 => ValType::I64,
25 WasmType::F32 => ValType::F32,
26 WasmType::F64 => ValType::F64,
27 }
28}
29
30struct TypeKey<'a> {
31 interface: &'a Interface,
32 ty: Type,
33}
34
35impl Hash for TypeKey<'_> {
36 fn hash<H: Hasher>(&self, state: &mut H) {
37 match self.ty {
38 Type::Id(id) => TypeDefKey::new(self.interface, &self.interface.types[id]).hash(state),
39 _ => self.ty.hash(state),
40 }
41 }
42}
43
44impl PartialEq for TypeKey<'_> {
45 fn eq(&self, other: &Self) -> bool {
46 match (self.ty, other.ty) {
47 (Type::Id(id), Type::Id(other_id)) => {
48 TypeDefKey::new(self.interface, &self.interface.types[id])
49 == TypeDefKey::new(other.interface, &other.interface.types[other_id])
50 }
51 _ => self.ty.eq(&other.ty),
52 }
53 }
54}
55
56impl Eq for TypeKey<'_> {}
57
58pub struct TypeDefKey<'a> {
60 interface: &'a Interface,
61 def: &'a TypeDef,
62}
63
64impl<'a> TypeDefKey<'a> {
65 fn new(interface: &'a Interface, def: &'a TypeDef) -> Self {
66 Self { interface, def }
67 }
68}
69
70impl PartialEq for TypeDefKey<'_> {
71 fn eq(&self, other: &Self) -> bool {
72 let def = self.def;
73 let other_def = other.def;
74 def.name == other_def.name
75 && match (&def.kind, &other_def.kind) {
76 (TypeDefKind::Record(r1), TypeDefKind::Record(r2)) => {
77 if r1.fields.len() != r2.fields.len() {
78 return false;
79 }
80
81 r1.fields.iter().zip(r2.fields.iter()).all(|(f1, f2)| {
82 f1.name == f2.name
83 && TypeKey {
84 interface: self.interface,
85 ty: f1.ty,
86 }
87 .eq(&TypeKey {
88 interface: other.interface,
89 ty: f2.ty,
90 })
91 })
92 }
93 (TypeDefKind::Tuple(t1), TypeDefKind::Tuple(t2)) => {
94 if t1.types.len() != t2.types.len() {
95 return false;
96 }
97
98 t1.types.iter().zip(t2.types.iter()).all(|(t1, t2)| {
99 TypeKey {
100 interface: self.interface,
101 ty: *t1,
102 }
103 .eq(&TypeKey {
104 interface: other.interface,
105 ty: *t2,
106 })
107 })
108 }
109 (TypeDefKind::Flags(f1), TypeDefKind::Flags(f2)) => {
110 if f1.flags.len() != f2.flags.len() {
111 return false;
112 }
113
114 f1.flags
115 .iter()
116 .zip(f2.flags.iter())
117 .all(|(f1, f2)| f1.name == f2.name)
118 }
119 (TypeDefKind::Variant(v1), TypeDefKind::Variant(v2)) => {
120 if v1.cases.len() != v2.cases.len() {
121 return false;
122 }
123
124 v1.cases.iter().zip(v2.cases.iter()).all(|(c1, c2)| {
125 c1.name == c2.name
126 && TypeKey {
127 interface: self.interface,
128 ty: c1.ty,
129 } == TypeKey {
130 interface: other.interface,
131 ty: c2.ty,
132 }
133 })
134 }
135 (TypeDefKind::Union(v1), TypeDefKind::Union(v2)) => {
136 if v1.cases.len() != v2.cases.len() {
137 return false;
138 }
139
140 v1.cases.iter().zip(v2.cases.iter()).all(|(c1, c2)| {
141 TypeKey {
142 interface: self.interface,
143 ty: c1.ty,
144 } == TypeKey {
145 interface: other.interface,
146 ty: c2.ty,
147 }
148 })
149 }
150 (TypeDefKind::Enum(e1), TypeDefKind::Enum(e2)) => {
151 if e1.cases.len() != e2.cases.len() {
152 return false;
153 }
154
155 e1.cases
156 .iter()
157 .zip(e2.cases.iter())
158 .all(|(c1, c2)| c1.name == c2.name)
159 }
160 (TypeDefKind::List(t1), TypeDefKind::List(t2))
161 | (TypeDefKind::Type(t1), TypeDefKind::Type(t2))
162 | (TypeDefKind::Option(t1), TypeDefKind::Option(t2)) => TypeKey {
163 interface: self.interface,
164 ty: *t1,
165 }
166 .eq(&TypeKey {
167 interface: other.interface,
168 ty: *t2,
169 }),
170 (TypeDefKind::Expected(e1), TypeDefKind::Expected(e2)) => {
171 TypeKey {
172 interface: self.interface,
173 ty: e1.ok,
174 } == TypeKey {
175 interface: other.interface,
176 ty: e2.ok,
177 } && TypeKey {
178 interface: self.interface,
179 ty: e1.err,
180 } == TypeKey {
181 interface: other.interface,
182 ty: e2.err,
183 }
184 }
185 _ => false,
186 }
187 }
188}
189
190impl Eq for TypeDefKey<'_> {}
191
192impl Hash for TypeDefKey<'_> {
193 fn hash<H: Hasher>(&self, state: &mut H) {
194 let def = self.def;
195 def.name.hash(state);
196 match &def.kind {
197 TypeDefKind::Record(r) => {
198 state.write_u8(0);
199 for f in &r.fields {
200 f.name.hash(state);
201 TypeKey {
202 interface: self.interface,
203 ty: f.ty,
204 }
205 .hash(state);
206 }
207 }
208 TypeDefKind::Tuple(t) => {
209 state.write_u8(1);
210 for ty in &t.types {
211 TypeKey {
212 interface: self.interface,
213 ty: *ty,
214 }
215 .hash(state);
216 }
217 }
218 TypeDefKind::Flags(r) => {
219 state.write_u8(2);
220 for f in &r.flags {
221 f.name.hash(state);
222 }
223 }
224 TypeDefKind::Variant(v) => {
225 state.write_u8(3);
226 for c in &v.cases {
227 c.name.hash(state);
228 TypeKey {
229 interface: self.interface,
230 ty: c.ty,
231 }
232 .hash(state);
233 }
234 }
235 TypeDefKind::Enum(e) => {
236 state.write_u8(4);
237 for c in &e.cases {
238 c.name.hash(state);
239 }
240 }
241 TypeDefKind::List(ty) => {
242 state.write_u8(5);
243 TypeKey {
244 interface: self.interface,
245 ty: *ty,
246 }
247 .hash(state);
248 }
249 TypeDefKind::Type(ty) => {
250 state.write_u8(6);
251 TypeKey {
252 interface: self.interface,
253 ty: *ty,
254 }
255 .hash(state);
256 }
257 TypeDefKind::Option(ty) => {
258 state.write_u8(7);
259 TypeKey {
260 interface: self.interface,
261 ty: *ty,
262 }
263 .hash(state);
264 }
265 TypeDefKind::Expected(e) => {
266 state.write_u8(8);
267 TypeKey {
268 interface: self.interface,
269 ty: e.ok,
270 }
271 .hash(state);
272 TypeKey {
273 interface: self.interface,
274 ty: e.err,
275 }
276 .hash(state);
277 }
278 TypeDefKind::Union(u) => {
279 state.write_u8(9);
280 u.cases.len().hash(state);
281 for case in u.cases.iter() {
282 TypeKey {
283 interface: self.interface,
284 ty: case.ty,
285 }
286 .hash(state);
287 }
288 }
289 TypeDefKind::Future(_) => todo!("hash for future"),
290 TypeDefKind::Stream(_) => todo!("hash for stream"),
291 }
292 }
293}
294
295pub struct FunctionKey<'a> {
297 interface: &'a Interface,
298 func: &'a Function,
299}
300
301impl PartialEq for FunctionKey<'_> {
302 fn eq(&self, other: &Self) -> bool {
303 if self.func.params.len() != other.func.params.len() {
304 return false;
305 }
306
307 self.func
308 .params
309 .iter()
310 .zip(other.func.params.iter())
311 .all(|((n1, t1), (n2, t2))| {
312 n1 == n2
313 && TypeKey {
314 interface: self.interface,
315 ty: *t1,
316 }
317 .eq(&TypeKey {
318 interface: other.interface,
319 ty: *t2,
320 })
321 })
322 && TypeKey {
323 interface: self.interface,
324 ty: self.func.result,
325 }
326 .eq(&TypeKey {
327 interface: other.interface,
328 ty: other.func.result,
329 })
330 }
331}
332
333impl Eq for FunctionKey<'_> {}
334
335impl Hash for FunctionKey<'_> {
336 fn hash<H: Hasher>(&self, state: &mut H) {
337 self.func.params.len().hash(state);
338 for (name, ty) in &self.func.params {
339 name.hash(state);
340 TypeKey {
341 interface: self.interface,
342 ty: *ty,
343 }
344 .hash(state);
345 }
346 TypeKey {
347 interface: self.interface,
348 ty: self.func.result,
349 }
350 .hash(state);
351 }
352}
353
354#[derive(Default)]
355struct InstanceTypeEncoder<'a> {
356 ty: InstanceType,
357 aliased_types: IndexMap<ComponentTypeRef, ComponentTypeRef>,
358 exported_types: IndexMap<&'a str, ComponentTypeRef>,
359}
360
361impl<'a> InstanceTypeEncoder<'a> {
362 fn export(&mut self, name: &'a str, type_ref: ComponentTypeRef) -> Result<()> {
363 match self.exported_types.entry(name) {
364 Entry::Occupied(e) => {
365 if *e.get() != type_ref {
366 bail!("duplicate export `{}`", name)
367 }
368 }
369 Entry::Vacant(entry) => {
370 entry.insert(type_ref);
371 let alias = self.alias_type(type_ref);
372 self.ty.export(name, alias);
373 }
374 }
375
376 Ok(())
377 }
378
379 fn alias_type(&mut self, type_ref: ComponentTypeRef) -> ComponentTypeRef {
380 match self.aliased_types.entry(type_ref) {
381 Entry::Occupied(e) => *e.get(),
382 Entry::Vacant(e) => {
383 let index = self.ty.type_count();
384 let (alias, outer_index) = match type_ref {
385 ComponentTypeRef::Module(outer) => (ComponentTypeRef::Module(index), outer),
386 ComponentTypeRef::Func(outer) => (ComponentTypeRef::Func(index), outer),
387 ComponentTypeRef::Value(ComponentValType::Primitive(_)) => unreachable!(),
388 ComponentTypeRef::Value(ComponentValType::Type(outer)) => (
389 ComponentTypeRef::Value(ComponentValType::Type(index)),
390 outer,
391 ),
392 ComponentTypeRef::Type(bounds, outer) => {
393 (ComponentTypeRef::Type(bounds, index), outer)
394 }
395 ComponentTypeRef::Instance(outer) => (ComponentTypeRef::Instance(index), outer),
396 ComponentTypeRef::Component(outer) => {
397 (ComponentTypeRef::Component(index), outer)
398 }
399 };
400
401 self.ty.alias_outer_type(1, outer_index);
402 e.insert(alias);
403 alias
404 }
405 }
406 }
407}
408
409#[derive(Default)]
410struct TypeEncoder<'a> {
411 types: ComponentTypeSection,
412 type_map: IndexMap<TypeDefKey<'a>, u32>,
413 func_type_map: IndexMap<FunctionKey<'a>, u32>,
414 exports: ComponentExportSection,
415 exported_types: IndexMap<&'a str, ComponentTypeRef>,
416}
417
418impl<'a> TypeEncoder<'a> {
419 fn finish(&self, component: &mut Component) {
420 if !self.types.is_empty() {
421 component.section(&self.types);
422 }
423
424 if !self.exports.is_empty() {
425 component.section(&self.exports);
426 }
427 }
428
429 fn encode_instance_imports(
430 &mut self,
431 interfaces: &'a [Interface],
432 required_imports: &IndexSet<&'a str>,
433 imports: &mut ImportEncoder<'a>,
434 ) -> Result<()> {
435 for import in interfaces {
436 if !required_imports.contains(import.name.as_str()) {
437 continue;
438 }
439
440 Self::validate_interface(import)?;
441
442 let mut instance = InstanceTypeEncoder::default();
443
444 for func in &import.functions {
445 Self::validate_function(func)?;
446
447 let index = self.encode_func_type(import, func, false)?;
448 instance.export(&func.name, ComponentTypeRef::Func(index))?;
449 }
450
451 let index = self.encode_instance_type(&instance.ty);
452 imports.import(import, ComponentTypeRef::Instance(index))?;
453 }
454
455 Ok(())
456 }
457
458 fn encode_func_types(
459 &mut self,
460 interfaces: impl Iterator<Item = (&'a Interface, bool)>,
461 export_func_types: bool,
462 ) -> Result<()> {
463 for (export, is_default) in interfaces {
464 Self::validate_interface(export)?;
465
466 for func in &export.functions {
469 Self::validate_function(func)?;
470
471 let index = self.encode_func_type(export, func, is_default)?;
472
473 if export_func_types {
474 self.export_type(&func.name, ComponentTypeRef::Func(index))?;
475 }
476 }
477 }
478
479 Ok(())
480 }
481
482 fn encode_instance_type(&mut self, ty: &InstanceType) -> u32 {
483 let index = self.types.len();
484 self.types.instance(ty);
485 index
486 }
487
488 fn encode_func_type(
489 &mut self,
490 interface: &'a Interface,
491 func: &'a Function,
492 export_named_types: bool,
493 ) -> Result<u32> {
494 let key = FunctionKey { interface, func };
495 if let Some(index) = self.func_type_map.get(&key) {
496 return Ok(*index);
497 }
498
499 let params: Vec<_> = func
501 .params
502 .iter()
503 .map(|(name, ty)| {
504 Ok((
505 Some(name.as_str()),
506 self.encode_valtype(interface, ty, export_named_types)?,
507 ))
508 })
509 .collect::<Result<_>>()?;
510 let result = self.encode_valtype(interface, &func.result, export_named_types)?;
511
512 let index = self.types.len();
514 self.types.function(params, result);
515 self.func_type_map.insert(key, index);
516 Ok(index)
517 }
518
519 fn encode_valtype(
520 &mut self,
521 interface: &'a Interface,
522 ty: &Type,
523 export_named_types: bool,
524 ) -> Result<ComponentValType> {
525 Ok(match ty {
526 Type::Unit => ComponentValType::Primitive(PrimitiveValType::Unit),
527 Type::Bool => ComponentValType::Primitive(PrimitiveValType::Bool),
528 Type::U8 => ComponentValType::Primitive(PrimitiveValType::U8),
529 Type::U16 => ComponentValType::Primitive(PrimitiveValType::U16),
530 Type::U32 => ComponentValType::Primitive(PrimitiveValType::U32),
531 Type::U64 => ComponentValType::Primitive(PrimitiveValType::U64),
532 Type::S8 => ComponentValType::Primitive(PrimitiveValType::S8),
533 Type::S16 => ComponentValType::Primitive(PrimitiveValType::S16),
534 Type::S32 => ComponentValType::Primitive(PrimitiveValType::S32),
535 Type::S64 => ComponentValType::Primitive(PrimitiveValType::S64),
536 Type::Float32 => ComponentValType::Primitive(PrimitiveValType::Float32),
537 Type::Float64 => ComponentValType::Primitive(PrimitiveValType::Float64),
538 Type::Char => ComponentValType::Primitive(PrimitiveValType::Char),
539 Type::String => ComponentValType::Primitive(PrimitiveValType::String),
540 Type::Id(id) => {
541 let ty = &interface.types[*id];
542 let key = TypeDefKey::new(interface, &interface.types[*id]);
543 let encoded = if let Some(index) = self.type_map.get(&key) {
544 ComponentValType::Type(*index)
545 } else {
546 let mut encoded = match &ty.kind {
547 TypeDefKind::Record(r) => {
548 self.encode_record(interface, r, export_named_types)?
549 }
550 TypeDefKind::Tuple(t) => {
551 self.encode_tuple(interface, t, export_named_types)?
552 }
553 TypeDefKind::Flags(r) => self.encode_flags(r)?,
554 TypeDefKind::Variant(v) => {
555 self.encode_variant(interface, v, export_named_types)?
556 }
557 TypeDefKind::Union(u) => {
558 self.encode_union(interface, u, export_named_types)?
559 }
560 TypeDefKind::Option(t) => {
561 self.encode_option(interface, t, export_named_types)?
562 }
563 TypeDefKind::Expected(e) => {
564 self.encode_expected(interface, e, export_named_types)?
565 }
566 TypeDefKind::Enum(e) => self.encode_enum(e)?,
567 TypeDefKind::List(ty) => {
568 let ty = self.encode_valtype(interface, ty, export_named_types)?;
569 let index = self.types.len();
570 let encoder = self.types.defined_type();
571 encoder.list(ty);
572 ComponentValType::Type(index)
573 }
574 TypeDefKind::Type(ty) => {
575 self.encode_valtype(interface, ty, export_named_types)?
576 }
577 TypeDefKind::Future(_) => todo!("encoding for future type"),
578 TypeDefKind::Stream(_) => todo!("encoding for stream type"),
579 };
580
581 if ty.name.is_some() {
582 if let ComponentValType::Primitive(ty) = encoded {
583 let index = self.types.len();
586 self.types.defined_type().primitive(ty);
587 encoded = ComponentValType::Type(index);
588 }
589 }
590
591 if let ComponentValType::Type(index) = encoded {
592 self.type_map.insert(key, index);
593 }
594
595 encoded
596 };
597
598 if export_named_types {
599 if let Some(name) = ty.name.as_deref() {
601 if let ComponentValType::Type(index) = encoded {
602 self.export_type(name, ComponentTypeRef::Type(TypeBounds::Eq, index))?;
603 }
604 }
605 }
606
607 encoded
608 }
609 Type::Handle(_) => {
610 bail!("the use of handle types in interfaces is not currently supported")
611 }
612 })
613 }
614
615 fn encode_record(
616 &mut self,
617 interface: &'a Interface,
618 record: &Record,
619 export_named_types: bool,
620 ) -> Result<ComponentValType> {
621 let fields = record
622 .fields
623 .iter()
624 .map(|f| {
625 Ok((
626 f.name.as_str(),
627 self.encode_valtype(interface, &f.ty, export_named_types)?,
628 ))
629 })
630 .collect::<Result<Vec<_>>>()?;
631
632 let index = self.types.len();
633 let encoder = self.types.defined_type();
634 encoder.record(fields);
635 Ok(ComponentValType::Type(index))
636 }
637
638 fn encode_tuple(
639 &mut self,
640 interface: &'a Interface,
641 tuple: &Tuple,
642 export_named_types: bool,
643 ) -> Result<ComponentValType> {
644 let tys = tuple
645 .types
646 .iter()
647 .map(|ty| self.encode_valtype(interface, ty, export_named_types))
648 .collect::<Result<Vec<_>>>()?;
649 let index = self.types.len();
650 let encoder = self.types.defined_type();
651 encoder.tuple(tys);
652 Ok(ComponentValType::Type(index))
653 }
654
655 fn encode_flags(&mut self, flags: &Flags) -> Result<ComponentValType> {
656 let index = self.types.len();
657 let encoder = self.types.defined_type();
658 encoder.flags(flags.flags.iter().map(|f| f.name.as_str()));
659 Ok(ComponentValType::Type(index))
660 }
661
662 fn encode_variant(
663 &mut self,
664 interface: &'a Interface,
665 variant: &Variant,
666 export_named_types: bool,
667 ) -> Result<ComponentValType> {
668 let cases = variant
669 .cases
670 .iter()
671 .map(|c| {
672 Ok((
673 c.name.as_str(),
674 self.encode_valtype(interface, &c.ty, export_named_types)?,
675 None, ))
677 })
678 .collect::<Result<Vec<_>>>()?;
679
680 let index = self.types.len();
681 let encoder = self.types.defined_type();
682 encoder.variant(cases);
683 Ok(ComponentValType::Type(index))
684 }
685
686 fn encode_union(
687 &mut self,
688 interface: &'a Interface,
689 union: &Union,
690 export_named_types: bool,
691 ) -> Result<ComponentValType> {
692 let tys = union
693 .cases
694 .iter()
695 .map(|c| self.encode_valtype(interface, &c.ty, export_named_types))
696 .collect::<Result<Vec<_>>>()?;
697
698 let index = self.types.len();
699 let encoder = self.types.defined_type();
700 encoder.union(tys);
701 Ok(ComponentValType::Type(index))
702 }
703
704 fn encode_option(
705 &mut self,
706 interface: &'a Interface,
707 payload: &Type,
708 export_named_types: bool,
709 ) -> Result<ComponentValType> {
710 let ty = self.encode_valtype(interface, payload, export_named_types)?;
711 let index = self.types.len();
712 let encoder = self.types.defined_type();
713 encoder.option(ty);
714 Ok(ComponentValType::Type(index))
715 }
716
717 fn encode_expected(
718 &mut self,
719 interface: &'a Interface,
720 expected: &Expected,
721 export_named_types: bool,
722 ) -> Result<ComponentValType> {
723 let ok = self.encode_valtype(interface, &expected.ok, export_named_types)?;
724 let error = self.encode_valtype(interface, &expected.err, export_named_types)?;
725 let index = self.types.len();
726 let encoder = self.types.defined_type();
727 encoder.expected(ok, error);
728 Ok(ComponentValType::Type(index))
729 }
730
731 fn encode_enum(&mut self, enum_: &Enum) -> Result<ComponentValType> {
732 let index = self.types.len();
733 let encoder = self.types.defined_type();
734 encoder.enum_type(enum_.cases.iter().map(|c| c.name.as_str()));
735 Ok(ComponentValType::Type(index))
736 }
737
738 fn export_type(&mut self, name: &'a str, type_ref: ComponentTypeRef) -> Result<()> {
739 match self.exported_types.entry(name) {
740 Entry::Occupied(e) => {
741 if *e.get() != type_ref {
742 bail!("duplicate export `{}`", name)
743 }
744 }
745 Entry::Vacant(entry) => {
746 entry.insert(type_ref);
747
748 let index = match type_ref {
749 ComponentTypeRef::Module(index) => index,
750 ComponentTypeRef::Func(index) => index,
751 ComponentTypeRef::Value(ComponentValType::Primitive(_)) => unreachable!(),
752 ComponentTypeRef::Value(ComponentValType::Type(index)) => index,
753 ComponentTypeRef::Type(_, index) => index,
754 ComponentTypeRef::Instance(index) => index,
755 ComponentTypeRef::Component(index) => index,
756 };
757
758 self.exports.export(name, ComponentExportKind::Type, index);
759 }
760 }
761
762 Ok(())
763 }
764
765 fn validate_interface(interface: &Interface) -> Result<()> {
766 if interface.resources.len() != 0 {
767 bail!("the use of resources in interfaces is not currently not supported");
768 }
769
770 Ok(())
771 }
772
773 fn validate_function(function: &Function) -> Result<()> {
774 if function.name.is_empty() {
775 bail!("interface has an unnamed function");
776 }
777
778 if !matches!(function.kind, FunctionKind::Freestanding) {
779 bail!(
780 "unsupported function `{}`: only free-standing functions are currently supported",
781 function.name
782 );
783 }
784
785 if function.is_async {
786 bail!(
787 "unsupported function `{}`: only synchronous functions are currently supported",
788 function.name
789 );
790 }
791
792 Ok(())
793 }
794}
795
796#[derive(Debug, Clone, Copy, PartialEq, Eq)]
797enum RequiredOptions {
798 None,
800 Memory,
802 Realloc,
804 All,
806}
807
808impl RequiredOptions {
809 fn for_types<'a>(interface: &Interface, mut types: impl Iterator<Item = &'a Type>) -> Self {
810 match types.try_fold(Self::None, |mut acc, ty| {
811 acc |= Self::for_type(interface, ty);
812 if acc == Self::All {
813 Err(acc)
816 } else {
817 Ok(acc)
818 }
819 }) {
820 Ok(o) | Err(o) => o,
821 }
822 }
823
824 fn for_type(interface: &Interface, ty: &Type) -> Self {
825 match ty {
826 Type::Id(id) => match &interface.types[*id].kind {
827 TypeDefKind::Record(r) => {
828 Self::for_types(interface, r.fields.iter().map(|f| &f.ty))
829 }
830 TypeDefKind::Tuple(t) => Self::for_types(interface, t.types.iter()),
831 TypeDefKind::Flags(_) => Self::None,
832 TypeDefKind::Option(t) => Self::for_type(interface, t),
833 TypeDefKind::Expected(e) => {
834 Self::for_type(interface, &e.ok) | Self::for_type(interface, &e.err)
835 }
836 TypeDefKind::Variant(v) => {
837 Self::for_types(interface, v.cases.iter().map(|c| &c.ty))
838 }
839 TypeDefKind::Union(v) => Self::for_types(interface, v.cases.iter().map(|c| &c.ty)),
840 TypeDefKind::Enum(_) => Self::None,
841 TypeDefKind::List(t) => {
842 Self::for_type(interface, t) | Self::Realloc
846 }
847 TypeDefKind::Type(t) => Self::for_type(interface, t),
848 TypeDefKind::Future(_) => todo!("encoding for future"),
849 TypeDefKind::Stream(_) => todo!("encoding for stream"),
850 },
851 Type::String => Self::All,
852 _ => Self::None,
853 }
854 }
855
856 fn for_function(interface: &Interface, function: &Function) -> Self {
857 Self::for_types(
858 interface,
859 function
860 .params
861 .iter()
862 .map(|(_, ty)| ty)
863 .chain([&function.result]),
864 )
865 }
866
867 fn into_iter(
868 self,
869 encoding: StringEncoding,
870 memory_index: Option<u32>,
871 realloc_index: Option<u32>,
872 ) -> Result<impl Iterator<Item = CanonicalOption> + ExactSizeIterator> {
873 #[derive(Default)]
874 struct Iter {
875 options: [Option<CanonicalOption>; 3],
876 current: usize,
877 count: usize,
878 }
879
880 impl Iter {
881 fn push(&mut self, option: CanonicalOption) {
882 assert!(self.count < self.options.len());
883 self.options[self.count] = Some(option);
884 self.count += 1;
885 }
886 }
887
888 impl Iterator for Iter {
889 type Item = CanonicalOption;
890
891 fn next(&mut self) -> Option<Self::Item> {
892 if self.current == self.count {
893 return None;
894 }
895 let option = self.options[self.current];
896 self.current += 1;
897 option
898 }
899
900 fn size_hint(&self) -> (usize, Option<usize>) {
901 (self.count - self.current, Some(self.count - self.current))
902 }
903 }
904
905 impl ExactSizeIterator for Iter {}
906
907 let mut iter = Iter::default();
908
909 if self == RequiredOptions::None {
910 return Ok(iter);
911 }
912
913 iter.push(CanonicalOption::Memory(memory_index.ok_or_else(|| {
914 anyhow!("module does not export a memory named `memory`")
915 })?));
916
917 if self == RequiredOptions::Memory {
918 return Ok(iter);
919 }
920
921 iter.push(CanonicalOption::Realloc(realloc_index.ok_or_else(
922 || anyhow!("module does not export a function named `canonical_abi_realloc`"),
923 )?));
924
925 if self == RequiredOptions::Realloc {
926 return Ok(iter);
927 }
928
929 assert_eq!(self, RequiredOptions::All);
930
931 iter.push(encoding.into());
932 Ok(iter)
933 }
934}
935
936impl BitOrAssign for RequiredOptions {
937 fn bitor_assign(&mut self, rhs: Self) {
938 *self = *self | rhs;
939 }
940}
941
942impl BitOr for RequiredOptions {
943 type Output = RequiredOptions;
944
945 fn bitor(self, rhs: Self) -> Self::Output {
946 match (self, rhs) {
947 (Self::All, _) | (_, Self::All) => Self::All,
948 (Self::Realloc, _) | (_, Self::Realloc) => Self::Realloc,
949 (Self::Memory, _) | (_, Self::Memory) => Self::Memory,
950 (Self::None, Self::None) => Self::None,
951 }
952 }
953}
954
955#[derive(Default)]
957struct EncodingState {
958 component: Component,
960 indexes: Indexes,
962 module_index: Option<u32>,
966 instance_index: Option<u32>,
970 memory_index: Option<u32>,
974 realloc_index: Option<u32>,
978 shim_instance_index: Option<u32>,
982 fixups_module_index: Option<u32>,
986}
987
988impl EncodingState {
989 fn encode_core_module(&mut self, module: &[u8]) -> u32 {
990 *self.module_index.get_or_insert_with(|| {
991 self.component.section(&wasm_encoder::RawSection {
992 id: ComponentSectionId::CoreModule.into(),
993 data: module,
994 });
995
996 self.indexes.alloc_core_module()
997 })
998 }
999
1000 fn encode_core_instantiation(
1001 &mut self,
1002 encoding: StringEncoding,
1003 imports: &ImportEncoder,
1004 has_memory: bool,
1005 has_realloc: bool,
1006 ) -> Result<()> {
1007 if imports.map.is_empty() {
1008 self.instantiate_core_module([], has_memory, has_realloc);
1009 return Ok(());
1010 }
1011
1012 self.encode_shim_instantiation(imports);
1014
1015 let mut instances = InstanceSection::new();
1016 let args: Vec<_> = imports
1017 .map
1018 .iter()
1019 .enumerate()
1020 .map(|(instance_index, (name, import))| {
1021 let mut exports = Vec::with_capacity(import.direct.len() + import.indirect.len());
1022
1023 let mut core_aliases = AliasSection::new();
1024 for lowering in &import.indirect {
1025 let index = self.alias_core_item(
1026 &mut core_aliases,
1027 self.shim_instance_index
1028 .expect("shim should be instantiated"),
1029 ExportKind::Func,
1030 &lowering.export_name,
1031 );
1032 exports.push((lowering.name, ExportKind::Func, index));
1033 }
1034 self.component.section(&core_aliases);
1035
1036 let mut aliases = ComponentAliasSection::new();
1037 let mut functions = CanonicalFunctionSection::new();
1038
1039 for lowering in &import.direct {
1040 let func_index =
1041 self.alias_func(&mut aliases, instance_index as u32, lowering.name);
1042 let core_func_index = self.lower_func(&mut functions, func_index, []);
1043 exports.push((lowering.name, ExportKind::Func, core_func_index));
1044 }
1045
1046 self.component.section(&aliases);
1047 self.component.section(&functions);
1048
1049 let index = self.instantiate_core_exports(&mut instances, exports);
1050 (*name, ModuleArg::Instance(index))
1051 })
1052 .collect();
1053
1054 self.component.section(&instances);
1055
1056 self.instantiate_core_module(args, has_memory, has_realloc);
1057 self.encode_indirect_lowerings(encoding, imports)
1058 }
1059
1060 fn encode_imports(&mut self, imports: &ImportEncoder) {
1061 let mut section = ComponentImportSection::default();
1062
1063 for (name, import) in &imports.map {
1064 section.import(name, import.ty);
1065 self.indexes.alloc_instance();
1066 }
1067
1068 if !section.is_empty() {
1069 self.component.section(§ion);
1070 }
1071 }
1072
1073 fn encode_exports<'a>(
1074 &mut self,
1075 encoding: StringEncoding,
1076 exports: impl Iterator<Item = (&'a Interface, bool)>,
1077 func_types: &IndexMap<FunctionKey<'a>, u32>,
1078 ) -> Result<()> {
1079 let core_instance_index = self.instance_index.expect("must be instantiated");
1080
1081 let mut section = ComponentExportSection::default();
1082 let mut instances = ComponentInstanceSection::new();
1083
1084 for (export, is_default) in exports {
1085 let mut aliases = AliasSection::new();
1087 let mut functions = CanonicalFunctionSection::new();
1088 let mut interface_exports = Vec::new();
1089 for func in &export.functions {
1090 let name =
1091 expected_export_name((!is_default).then(|| export.name.as_str()), &func.name);
1092
1093 let core_func_index = self.alias_core_item(
1094 &mut aliases,
1095 core_instance_index,
1096 ExportKind::Func,
1097 name.as_ref(),
1098 );
1099
1100 let ty = *func_types
1101 .get(&FunctionKey {
1102 interface: export,
1103 func,
1104 })
1105 .expect("the type should be encoded");
1106
1107 let sig = export.wasm_signature(AbiVariant::GuestExport, func);
1108 let options = RequiredOptions::for_function(export, func)
1109 | (if sig.retptr || sig.indirect_params {
1110 RequiredOptions::Memory
1111 } else {
1112 RequiredOptions::None
1113 });
1114
1115 let func_index = self.lift_func(
1117 &mut functions,
1118 core_func_index,
1119 ty,
1120 options.into_iter(encoding, self.memory_index, self.realloc_index)?,
1121 );
1122
1123 if is_default {
1124 section.export(&func.name, ComponentExportKind::Func, func_index);
1126 } else {
1127 interface_exports.push((
1129 func.name.as_str(),
1130 ComponentExportKind::Func,
1131 func_index,
1132 ));
1133 }
1134 }
1135
1136 self.component.section(&aliases);
1137 self.component.section(&functions);
1138
1139 if !interface_exports.is_empty() {
1140 if export.name.is_empty() {
1141 bail!("cannot export an unnamed interface");
1142 }
1143
1144 let instance_index = self.instantiate_exports(&mut instances, interface_exports);
1145 section.export(&export.name, ComponentExportKind::Instance, instance_index);
1146 }
1147 }
1148
1149 if !instances.is_empty() {
1150 self.component.section(&instances);
1151 }
1152
1153 if !section.is_empty() {
1154 self.component.section(§ion);
1155 }
1156
1157 Ok(())
1158 }
1159
1160 fn encode_shim_instantiation(&mut self, imports: &ImportEncoder) {
1161 if imports.indirect_count == 0 {
1162 return;
1163 }
1164
1165 assert!(self.shim_instance_index.is_none());
1166 assert!(self.fixups_module_index.is_none());
1167
1168 let mut types = TypeSection::new();
1177 let mut tables = TableSection::new();
1178 let mut functions = FunctionSection::new();
1179 let mut exports = ExportSection::new();
1180 let mut code = CodeSection::new();
1181 let mut sigs = IndexMap::new();
1182 let mut imports_section = ImportSection::new();
1183 let mut elements = ElementSection::new();
1184 let mut func_indexes = Vec::new();
1185
1186 let mut func_index = 0;
1187 for import in imports.map.values() {
1188 for lowering in &import.indirect {
1189 let type_index = *sigs.entry(&lowering.sig).or_insert_with(|| {
1190 let index = types.len();
1191 types.function(
1192 lowering.sig.params.iter().map(to_val_type),
1193 lowering.sig.results.iter().map(to_val_type),
1194 );
1195 index
1196 });
1197
1198 functions.function(type_index);
1199 Self::encode_shim_function(
1200 type_index,
1201 func_index,
1202 &mut code,
1203 lowering.sig.params.len() as u32,
1204 );
1205 exports.export(&lowering.export_name, ExportKind::Func, func_index);
1206
1207 imports_section.import("", &lowering.export_name, EntityType::Function(type_index));
1208 func_indexes.push(func_index);
1209
1210 func_index += 1;
1211 }
1212 }
1213
1214 let table_type = TableType {
1215 element_type: ValType::FuncRef,
1216 minimum: func_index,
1217 maximum: Some(func_index),
1218 };
1219
1220 tables.table(table_type);
1221
1222 exports.export(INDIRECT_TABLE_NAME, ExportKind::Table, 0);
1223 imports_section.import("", INDIRECT_TABLE_NAME, table_type);
1224
1225 elements.active(
1226 None,
1227 &Instruction::I32Const(0),
1228 ValType::FuncRef,
1229 Elements::Functions(&func_indexes),
1230 );
1231
1232 let mut shim = Module::new();
1233 shim.section(&types);
1234 shim.section(&functions);
1235 shim.section(&tables);
1236 shim.section(&exports);
1237 shim.section(&code);
1238
1239 let mut fixups = Module::default();
1240 fixups.section(&types);
1241 fixups.section(&imports_section);
1242 fixups.section(&elements);
1243
1244 let shim_module_index = self.indexes.alloc_core_module();
1245 self.component.section(&ModuleSection(&shim));
1246
1247 self.fixups_module_index = Some(self.indexes.alloc_core_module());
1248 self.component.section(&ModuleSection(&fixups));
1249
1250 let mut instances = InstanceSection::default();
1251 self.shim_instance_index = Some(self.instantiate(&mut instances, shim_module_index, []));
1252 self.component.section(&instances);
1253 }
1254
1255 fn encode_shim_function(
1256 type_index: u32,
1257 func_index: u32,
1258 code: &mut CodeSection,
1259 param_count: u32,
1260 ) {
1261 let mut func = wasm_encoder::Function::new(std::iter::empty());
1262 for i in 0..param_count {
1263 func.instruction(&Instruction::LocalGet(i));
1264 }
1265 func.instruction(&Instruction::I32Const(func_index as i32));
1266 func.instruction(&Instruction::CallIndirect {
1267 ty: type_index,
1268 table: 0,
1269 });
1270 func.instruction(&Instruction::End);
1271 code.function(&func);
1272 }
1273
1274 fn encode_indirect_lowerings(
1275 &mut self,
1276 encoding: StringEncoding,
1277 imports: &ImportEncoder,
1278 ) -> Result<()> {
1279 if imports.indirect_count == 0 {
1280 return Ok(());
1281 }
1282
1283 let shim_instance_index = self
1284 .shim_instance_index
1285 .expect("must have an instantiated shim");
1286
1287 let mut core_aliases = AliasSection::new();
1288 let table_index = self.alias_core_item(
1289 &mut core_aliases,
1290 shim_instance_index,
1291 ExportKind::Table,
1292 INDIRECT_TABLE_NAME,
1293 );
1294 self.component.section(&core_aliases);
1295
1296 let mut exports = Vec::with_capacity(imports.indirect_count as usize);
1297 exports.push((INDIRECT_TABLE_NAME, ExportKind::Table, table_index));
1298
1299 let mut aliases = ComponentAliasSection::new();
1300 let mut functions = CanonicalFunctionSection::new();
1301 for (instance_index, import) in imports.map.values().enumerate() {
1302 for lowering in &import.indirect {
1303 let func_index =
1304 self.alias_func(&mut aliases, instance_index as u32, lowering.name);
1305
1306 let core_func_index = self.lower_func(
1307 &mut functions,
1308 func_index,
1309 lowering
1310 .options
1311 .into_iter(encoding, self.memory_index, self.realloc_index)?,
1312 );
1313
1314 exports.push((
1315 lowering.export_name.as_str(),
1316 ExportKind::Func,
1317 core_func_index,
1318 ));
1319 }
1320 }
1321
1322 self.component.section(&aliases);
1323 self.component.section(&functions);
1324
1325 let mut instances = InstanceSection::new();
1326 let instance_index = self.instantiate_core_exports(&mut instances, exports);
1327 self.instantiate(
1328 &mut instances,
1329 self.fixups_module_index.expect("must have fixup module"),
1330 [("", ModuleArg::Instance(instance_index))],
1331 );
1332 self.component.section(&instances);
1333 Ok(())
1334 }
1335
1336 fn instantiate_core_module<'a, A>(&mut self, args: A, has_memory: bool, has_realloc: bool)
1337 where
1338 A: IntoIterator<Item = (&'a str, ModuleArg)>,
1339 A::IntoIter: ExactSizeIterator,
1340 {
1341 assert!(self.instance_index.is_none());
1342
1343 let mut instances = InstanceSection::new();
1344 let mut aliases = AliasSection::new();
1345
1346 let instance_index = self.instantiate(
1347 &mut instances,
1348 self.module_index.expect("core module encoded"),
1349 args,
1350 );
1351
1352 if has_memory {
1353 self.memory_index = Some(self.alias_core_item(
1354 &mut aliases,
1355 instance_index,
1356 ExportKind::Memory,
1357 "memory",
1358 ));
1359 }
1360
1361 if has_realloc {
1362 self.realloc_index = Some(self.alias_core_item(
1363 &mut aliases,
1364 instance_index,
1365 ExportKind::Func,
1366 "canonical_abi_realloc",
1367 ));
1368 }
1369
1370 self.component.section(&instances);
1371 self.component.section(&aliases);
1372
1373 self.instance_index = Some(instance_index);
1374 }
1375
1376 fn instantiate<'a, A>(
1377 &mut self,
1378 instances: &mut InstanceSection,
1379 module_index: u32,
1380 args: A,
1381 ) -> u32
1382 where
1383 A: IntoIterator<Item = (&'a str, ModuleArg)>,
1384 A::IntoIter: ExactSizeIterator,
1385 {
1386 instances.instantiate(module_index, args);
1387 self.indexes.alloc_core_instance()
1388 }
1389
1390 fn alias_core_item(
1391 &mut self,
1392 aliases: &mut AliasSection,
1393 instance: u32,
1394 kind: ExportKind,
1395 name: &str,
1396 ) -> u32 {
1397 aliases.instance_export(instance, kind, name);
1398 match kind {
1399 ExportKind::Func => self.indexes.alloc_core_func(),
1400 ExportKind::Table => self.indexes.alloc_core_table(),
1401 ExportKind::Memory => self.indexes.alloc_core_memory(),
1402 ExportKind::Global | ExportKind::Tag => unreachable!(),
1403 }
1404 }
1405
1406 fn alias_func(
1407 &mut self,
1408 aliases: &mut ComponentAliasSection,
1409 instance: u32,
1410 name: &str,
1411 ) -> u32 {
1412 aliases.instance_export(instance, ComponentExportKind::Func, name);
1413 self.indexes.alloc_func()
1414 }
1415
1416 fn lower_func<O>(
1417 &mut self,
1418 functions: &mut CanonicalFunctionSection,
1419 func_index: u32,
1420 options: O,
1421 ) -> u32
1422 where
1423 O: IntoIterator<Item = CanonicalOption>,
1424 O::IntoIter: ExactSizeIterator,
1425 {
1426 functions.lower(func_index, options);
1427 self.indexes.alloc_core_func()
1428 }
1429
1430 fn lift_func<O>(
1431 &mut self,
1432 functions: &mut CanonicalFunctionSection,
1433 core_func_index: u32,
1434 type_index: u32,
1435 options: O,
1436 ) -> u32
1437 where
1438 O: IntoIterator<Item = CanonicalOption>,
1439 O::IntoIter: ExactSizeIterator,
1440 {
1441 functions.lift(core_func_index, type_index, options);
1442 self.indexes.alloc_func()
1443 }
1444
1445 fn instantiate_core_exports<'a, E>(
1446 &mut self,
1447 instances: &mut InstanceSection,
1448 exports: E,
1449 ) -> u32
1450 where
1451 E: IntoIterator<Item = (&'a str, ExportKind, u32)>,
1452 E::IntoIter: ExactSizeIterator,
1453 {
1454 instances.export_items(exports);
1455 self.indexes.alloc_core_instance()
1456 }
1457
1458 fn instantiate_exports<'a, E>(
1459 &mut self,
1460 instances: &mut ComponentInstanceSection,
1461 exports: E,
1462 ) -> u32
1463 where
1464 E: IntoIterator<Item = (&'a str, ComponentExportKind, u32)>,
1465 E::IntoIter: ExactSizeIterator,
1466 {
1467 instances.export_items(exports);
1468 self.indexes.alloc_instance()
1469 }
1470}
1471
1472#[derive(Debug)]
1473struct DirectLowering<'a> {
1474 name: &'a str,
1475}
1476
1477#[derive(Debug)]
1478struct IndirectLowering<'a> {
1479 name: &'a str,
1480 sig: WasmSignature,
1481 options: RequiredOptions,
1482 export_name: String,
1483}
1484
1485#[derive(Debug)]
1486struct ImportedInterface<'a> {
1487 ty: ComponentTypeRef,
1488 direct: Vec<DirectLowering<'a>>,
1489 indirect: Vec<IndirectLowering<'a>>,
1490}
1491
1492#[derive(Debug, Default)]
1505struct ImportEncoder<'a> {
1506 map: IndexMap<&'a str, ImportedInterface<'a>>,
1507 direct_count: u32,
1508 indirect_count: u32,
1509}
1510
1511impl<'a> ImportEncoder<'a> {
1512 fn import(&mut self, interface: &'a Interface, ty: ComponentTypeRef) -> Result<()> {
1513 match self.map.entry(&interface.name) {
1514 indexmap::map::Entry::Occupied(e) => {
1515 if e.get().ty != ty {
1516 bail!("duplicate import `{}`", interface.name)
1517 }
1518 }
1519 indexmap::map::Entry::Vacant(e) => {
1520 let mut direct = Vec::new();
1521 let mut indirect = Vec::new();
1522 for f in &interface.functions {
1523 let sig = interface.wasm_signature(AbiVariant::GuestImport, f);
1524 let options = RequiredOptions::for_function(interface, f)
1525 | (if sig.retptr || sig.indirect_params {
1526 RequiredOptions::Memory
1527 } else {
1528 RequiredOptions::None
1529 });
1530
1531 match options {
1532 RequiredOptions::All
1533 | RequiredOptions::Realloc
1534 | RequiredOptions::Memory => {
1535 let element_index = self.indirect_count;
1536 self.indirect_count += 1;
1537 indirect.push(IndirectLowering {
1538 name: &f.name,
1539 sig,
1540 options,
1541 export_name: element_index.to_string(),
1542 });
1543 }
1544 RequiredOptions::None => {
1545 self.direct_count += 1;
1546 direct.push(DirectLowering { name: &f.name });
1547 }
1548 }
1549 }
1550
1551 e.insert(ImportedInterface {
1552 ty,
1553 direct,
1554 indirect,
1555 });
1556 }
1557 }
1558
1559 Ok(())
1560 }
1561}
1562
1563#[derive(Default)]
1564struct Indexes {
1565 core_modules: u32,
1567 core_funcs: u32,
1568 core_memories: u32,
1569 core_tables: u32,
1570 core_instances: u32,
1571
1572 funcs: u32,
1574 instances: u32,
1575}
1576
1577impl Indexes {
1578 fn alloc_core_module(&mut self) -> u32 {
1579 let index = self.core_modules;
1580 self.core_modules += 1;
1581 index
1582 }
1583
1584 fn alloc_core_func(&mut self) -> u32 {
1585 let index = self.core_funcs;
1586 self.core_funcs += 1;
1587 index
1588 }
1589
1590 fn alloc_core_memory(&mut self) -> u32 {
1591 let index = self.core_memories;
1592 self.core_memories += 1;
1593 index
1594 }
1595
1596 fn alloc_core_table(&mut self) -> u32 {
1597 let index = self.core_tables;
1598 self.core_tables += 1;
1599 index
1600 }
1601
1602 fn alloc_core_instance(&mut self) -> u32 {
1603 let index = self.core_instances;
1604 self.core_instances += 1;
1605 index
1606 }
1607
1608 fn alloc_func(&mut self) -> u32 {
1609 let index = self.funcs;
1610 self.funcs += 1;
1611 index
1612 }
1613
1614 fn alloc_instance(&mut self) -> u32 {
1615 let index = self.instances;
1616 self.instances += 1;
1617 index
1618 }
1619}
1620
1621#[derive(Default)]
1623pub struct ComponentEncoder<'a> {
1624 module: &'a [u8],
1625 encoding: StringEncoding,
1626 interface: Option<&'a Interface>,
1627 imports: &'a [Interface],
1628 exports: &'a [Interface],
1629 validate: bool,
1630 types_only: bool,
1631}
1632
1633impl<'a> ComponentEncoder<'a> {
1634 pub fn module(mut self, module: &'a [u8]) -> Self {
1636 self.module = module;
1637 self
1638 }
1639
1640 pub fn encoding(mut self, encoding: StringEncoding) -> Self {
1642 self.encoding = encoding;
1643 self
1644 }
1645
1646 pub fn validate(mut self, validate: bool) -> Self {
1648 self.validate = validate;
1649 self
1650 }
1651
1652 pub fn interface(mut self, interface: &'a Interface) -> Self {
1654 self.interface = Some(interface);
1655 self
1656 }
1657
1658 pub fn imports(mut self, imports: &'a [Interface]) -> Self {
1660 self.imports = imports;
1661 self
1662 }
1663
1664 pub fn exports(mut self, exports: &'a [Interface]) -> Self {
1666 self.exports = exports;
1667 self
1668 }
1669
1670 pub fn encode(&self) -> Result<Vec<u8>> {
1672 let (required_imports, has_memory, has_realloc) = if !self.module.is_empty() {
1673 validate_module(self.module, &self.interface, self.imports, self.exports)?
1674 } else {
1675 (Default::default(), false, false)
1676 };
1677
1678 let exports = self
1679 .interface
1680 .iter()
1681 .copied()
1682 .map(|i| (i, true))
1683 .chain(self.exports.iter().map(|i| (i, false)));
1684
1685 let mut state = EncodingState::default();
1686 let mut types = TypeEncoder::default();
1687 let mut imports = ImportEncoder::default();
1688 types.encode_instance_imports(self.imports, &required_imports, &mut imports)?;
1689 types.encode_func_types(exports.clone(), false)?;
1690 types.finish(&mut state.component);
1691
1692 if self.types_only {
1693 if !self.module.is_empty() {
1694 bail!("a module cannot be specified for a types-only encoding");
1695 }
1696 } else {
1697 if self.module.is_empty() {
1698 bail!("a module is required when encoding a component");
1699 }
1700
1701 state.encode_imports(&imports);
1702 state.encode_core_module(self.module);
1703 state.encode_core_instantiation(self.encoding, &imports, has_memory, has_realloc)?;
1704 state.encode_exports(self.encoding, exports, &types.func_type_map)?;
1705 }
1706
1707 let bytes = state.component.finish();
1708
1709 if self.validate {
1710 let mut validator = Validator::new_with_features(WasmFeatures {
1711 component_model: true,
1712 ..Default::default()
1713 });
1714
1715 validator
1716 .validate_all(&bytes)
1717 .context("failed to validate component output")?;
1718 }
1719
1720 Ok(bytes)
1721 }
1722}
1723
1724pub struct InterfaceEncoder<'a> {
1729 interface: &'a Interface,
1730 validate: bool,
1731}
1732
1733impl<'a> InterfaceEncoder<'a> {
1734 pub fn new(interface: &'a Interface) -> Self {
1736 Self {
1737 interface,
1738 validate: false,
1739 }
1740 }
1741
1742 pub fn validate(mut self, validate: bool) -> Self {
1744 self.validate = validate;
1745 self
1746 }
1747
1748 pub fn encode(&self) -> Result<Vec<u8>> {
1750 let mut component = Component::default();
1751
1752 let mut types = TypeEncoder::default();
1753 types.encode_func_types([(self.interface, true)].into_iter(), true)?;
1754 types.finish(&mut component);
1755
1756 let bytes = component.finish();
1757
1758 if self.validate {
1759 let mut validator = Validator::new_with_features(WasmFeatures {
1760 component_model: true,
1761 ..Default::default()
1762 });
1763
1764 validator
1765 .validate_all(&bytes)
1766 .context("failed to validate component output")?;
1767 }
1768
1769 Ok(bytes)
1770 }
1771}