wasmer_wit_component/
encoding.rs

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
58/// Represents a key type for interface type definitions.
59pub 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
295/// Represents a key type for interface function definitions.
296pub 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            // TODO: stick interface documentation in a custom section?
467
468            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        // Encode all referenced parameter types from this function.
500        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        // Encode the function type
513        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                            // Named primitive types need entries in the type section, so
584                            // convert this to a type reference
585                            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                    // Named types need to be exported
600                    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, // TODO: support defaulting case values in the future
676                ))
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    // No required options.
799    None,
800    // Only the memory option is required.
801    Memory,
802    // The realloc option (and, by extension, the memory option) is required.
803    Realloc,
804    // The encoding, realloc, and memory options are required.
805    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                // If something requires all the options, then we're done searching.
814                // Returning an error here so that the operation terminates early.
815                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                    // Lists need at least the `realloc` option, but may require
843                    // the encoding option if there's a string somewhere in the
844                    // type.
845                    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/// State relating to encoding a component.
956#[derive(Default)]
957struct EncodingState {
958    /// The component being encoded.
959    component: Component,
960    /// The various index spaces used in the encoding.
961    indexes: Indexes,
962    /// The index into the core module index space for the inner core module.
963    ///
964    /// If `None`, the core module has not been encoded.
965    module_index: Option<u32>,
966    /// The index into the core instance index space for the inner core module.
967    ///
968    /// If `None`, the core module has not been instantiated.
969    instance_index: Option<u32>,
970    /// The index in the core memory index space for the exported memory.
971    ///
972    /// If `None`, then the memory has not yet been aliased.
973    memory_index: Option<u32>,
974    /// The index in the core function index space for the realloc function.
975    ///
976    /// If `None`, then the realloc function has not yet been aliased.
977    realloc_index: Option<u32>,
978    /// The index of the shim instance used for lowering imports into the core instance.
979    ///
980    /// If `None`, then the shim instance how not yet been encoded.
981    shim_instance_index: Option<u32>,
982    /// The index of the fixups module to instantiate to fill in the lowered imports.
983    ///
984    /// If `None`, then a fixup module has not yet been encoded.
985    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        // Encode a shim instantiation if needed
1013        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(&section);
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            // Alias the exports from the core module
1086            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                // TODO: support the post-return option somehow (not yet supported in wit-bindgen)
1116                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                    // Directly export the lifted function
1125                    section.export(&func.name, ComponentExportKind::Func, func_index);
1126                } else {
1127                    // Otherwise, add it to the list for later instantiation
1128                    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(&section);
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        // This function encodes two modules:
1169        // - A shim module that defines a table and exports functions
1170        //   that indirectly call through the table.
1171        // - A fixup module that imports that table and a set of functions
1172        //   and populates the imported table via active element segments. The
1173        //   fixup module is used to populate the shim's table once the
1174        //   imported functions have been lowered.
1175
1176        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/// The import encoder handles indirect lowering of any imports
1493/// that require canonical options to be specified.
1494///
1495/// Lowering of such imports is done through a shim module that
1496/// defines a table of functions and exports functions that indirectly
1497/// call through the table.
1498///
1499/// Another module is responsible for "fixing-up" the table of functions
1500/// once the functions have been lowered, after the core module is instantiated.
1501///
1502/// If a lowering does not require canonical options, the import is lowered before
1503/// the core module is instantiated and passed directly as an instantiation argument.
1504#[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 index spaces
1566    core_modules: u32,
1567    core_funcs: u32,
1568    core_memories: u32,
1569    core_tables: u32,
1570    core_instances: u32,
1571
1572    // Component index spaces
1573    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/// An encoder of components based on `wit` interface definitions.
1622#[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    /// Set the core module to encode as a component.
1635    pub fn module(mut self, module: &'a [u8]) -> Self {
1636        self.module = module;
1637        self
1638    }
1639
1640    /// Set the string encoding expected by the core module.
1641    pub fn encoding(mut self, encoding: StringEncoding) -> Self {
1642        self.encoding = encoding;
1643        self
1644    }
1645
1646    /// Sets whether or not the encoder will validate its output.
1647    pub fn validate(mut self, validate: bool) -> Self {
1648        self.validate = validate;
1649        self
1650    }
1651
1652    /// Set the default interface exported by the component.
1653    pub fn interface(mut self, interface: &'a Interface) -> Self {
1654        self.interface = Some(interface);
1655        self
1656    }
1657
1658    /// Set the interfaces the component imports.
1659    pub fn imports(mut self, imports: &'a [Interface]) -> Self {
1660        self.imports = imports;
1661        self
1662    }
1663
1664    /// Set the interfaces the component exports.
1665    pub fn exports(mut self, exports: &'a [Interface]) -> Self {
1666        self.exports = exports;
1667        self
1668    }
1669
1670    /// Encode the component and return the bytes.
1671    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
1724/// An encoder for a single interface definition.
1725///
1726/// The resulting component will only encode the type information
1727/// of the interface.
1728pub struct InterfaceEncoder<'a> {
1729    interface: &'a Interface,
1730    validate: bool,
1731}
1732
1733impl<'a> InterfaceEncoder<'a> {
1734    /// Create a new encoder for the given interface.
1735    pub fn new(interface: &'a Interface) -> Self {
1736        Self {
1737            interface,
1738            validate: false,
1739        }
1740    }
1741
1742    /// Sets whether or not the encoder will validate its output.
1743    pub fn validate(mut self, validate: bool) -> Self {
1744        self.validate = validate;
1745        self
1746    }
1747
1748    /// Encode the interface as a component and return the bytes.
1749    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}