golem_wasm_ast/component/
writer.rs

1// Copyright 2024-2025 Golem Cloud
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::component::*;
16use crate::core::{Data, ExportDesc, RetainsInstructions};
17
18impl From<&InstantiationArgRef> for wasm_encoder::ModuleArg {
19    fn from(value: &InstantiationArgRef) -> Self {
20        match value {
21            InstantiationArgRef::Instance(instance_idx) => {
22                wasm_encoder::ModuleArg::Instance(*instance_idx)
23            }
24        }
25    }
26}
27
28impl From<&InstantiationArg> for (String, wasm_encoder::ModuleArg) {
29    fn from(value: &InstantiationArg) -> Self {
30        (value.name.clone(), (&value.arg_ref).into())
31    }
32}
33
34impl From<&Export> for (String, wasm_encoder::ExportKind, u32) {
35    fn from(value: &Export) -> Self {
36        let (kind, index) = match value.desc {
37            ExportDesc::Func(func_idx) => (wasm_encoder::ExportKind::Func, func_idx),
38            ExportDesc::Table(table_idx) => (wasm_encoder::ExportKind::Table, table_idx),
39            ExportDesc::Mem(mem_idx) => (wasm_encoder::ExportKind::Memory, mem_idx),
40            ExportDesc::Global(global_idx) => (wasm_encoder::ExportKind::Global, global_idx),
41        };
42        (value.name.clone(), kind, index)
43    }
44}
45
46impl From<&Instance> for wasm_encoder::InstanceSection {
47    fn from(value: &Instance) -> Self {
48        let mut section = wasm_encoder::InstanceSection::new();
49        add_to_core_instance_section(&mut section, value);
50        section
51    }
52}
53
54fn add_to_core_instance_section(section: &mut wasm_encoder::InstanceSection, value: &Instance) {
55    match value {
56        Instance::Instantiate { module_idx, args } => {
57            section.instantiate(
58                *module_idx,
59                args.iter()
60                    .map(|instantiation_arg| instantiation_arg.into()),
61            );
62        }
63        Instance::FromExports { exports } => {
64            section.export_items(exports.iter().map(|export| export.into()));
65        }
66    }
67}
68
69fn add_to_module_type(
70    module_type: &mut wasm_encoder::ModuleType,
71    value: &Vec<ModuleDeclaration>,
72) -> Result<(), String> {
73    for module_declaration in value {
74        match module_declaration {
75            ModuleDeclaration::Type { typ } => {
76                module_type.ty().function(
77                    typ.input.values.iter().map(|val_type| val_type.into()),
78                    typ.output.values.iter().map(|val_type| val_type.into()),
79                );
80            }
81            ModuleDeclaration::Export { name, desc } => {
82                module_type.export(name, desc.into());
83            }
84            ModuleDeclaration::OuterAlias { kind, target } => match kind {
85                OuterAliasKind::CoreType => {
86                    module_type.alias_outer_core_type(target.count, target.index);
87                }
88                OuterAliasKind::CoreModule => {
89                    return Err("CoreModule outer alias is not supported".to_string())
90                }
91                OuterAliasKind::Type => return Err("Type outer alias is not supported".to_string()),
92                OuterAliasKind::Component => {
93                    return Err("Component outer alias is not supported".to_string())
94                }
95            },
96            ModuleDeclaration::Import { import } => {
97                module_type.import(&import.module, &import.name, (&import.desc).into());
98            }
99        }
100    }
101    Ok(())
102}
103
104impl TryFrom<&CoreType> for wasm_encoder::CoreTypeSection {
105    type Error = String;
106
107    fn try_from(value: &CoreType) -> Result<Self, Self::Error> {
108        let mut section = wasm_encoder::CoreTypeSection::new();
109        add_to_core_type_section(&mut section, value)?;
110        Ok(section)
111    }
112}
113
114fn add_to_core_type_encoder(
115    encoder: wasm_encoder::ComponentCoreTypeEncoder,
116    value: &CoreType,
117) -> Result<(), String> {
118    match value {
119        CoreType::Function(func_type) => {
120            encoder.core().function(
121                func_type
122                    .input
123                    .values
124                    .iter()
125                    .map(|val_type| val_type.into()),
126                func_type
127                    .output
128                    .values
129                    .iter()
130                    .map(|val_type| val_type.into()),
131            );
132        }
133        CoreType::Module(module_declarations) => {
134            let mut module_type = wasm_encoder::ModuleType::new();
135            add_to_module_type(&mut module_type, module_declarations)?;
136            encoder.module(&module_type);
137        }
138    }
139    Ok(())
140}
141
142fn add_to_core_type_section(
143    section: &mut wasm_encoder::CoreTypeSection,
144    value: &CoreType,
145) -> Result<(), String> {
146    add_to_core_type_encoder(section.ty(), value)
147}
148
149impl From<&ComponentExternalKind> for wasm_encoder::ComponentExportKind {
150    fn from(value: &ComponentExternalKind) -> Self {
151        match value {
152            ComponentExternalKind::Module => wasm_encoder::ComponentExportKind::Module,
153            ComponentExternalKind::Func => wasm_encoder::ComponentExportKind::Func,
154            ComponentExternalKind::Value => wasm_encoder::ComponentExportKind::Value,
155            ComponentExternalKind::Type => wasm_encoder::ComponentExportKind::Type,
156            ComponentExternalKind::Instance => wasm_encoder::ComponentExportKind::Instance,
157            ComponentExternalKind::Component => wasm_encoder::ComponentExportKind::Component,
158        }
159    }
160}
161
162impl From<&ComponentInstantiationArg> for (String, wasm_encoder::ComponentExportKind, u32) {
163    fn from(value: &ComponentInstantiationArg) -> Self {
164        (value.name.clone(), (&value.kind).into(), value.idx)
165    }
166}
167
168impl<'a> From<&'a ComponentExport> for (&'a str, wasm_encoder::ComponentExportKind, u32) {
169    fn from(value: &'a ComponentExport) -> Self {
170        let name: &'a str = (&value.name).into();
171        (name, (&value.kind).into(), value.idx)
172    }
173}
174
175impl From<&ComponentInstance> for wasm_encoder::ComponentInstanceSection {
176    fn from(value: &ComponentInstance) -> Self {
177        let mut section = wasm_encoder::ComponentInstanceSection::new();
178        add_to_component_instance_section(&mut section, value);
179        section
180    }
181}
182
183fn add_to_component_instance_section(
184    section: &mut wasm_encoder::ComponentInstanceSection,
185    value: &ComponentInstance,
186) {
187    match value {
188        ComponentInstance::Instantiate {
189            component_idx,
190            args,
191        } => {
192            section.instantiate(
193                *component_idx,
194                args.iter()
195                    .map(|instantiation_arg| instantiation_arg.into()),
196            );
197        }
198        ComponentInstance::FromExports { exports } => {
199            section.export_items(exports.iter().map(|export| export.into()));
200        }
201    }
202}
203
204impl From<&OuterAliasKind> for wasm_encoder::ComponentOuterAliasKind {
205    fn from(value: &OuterAliasKind) -> Self {
206        match value {
207            OuterAliasKind::CoreModule => wasm_encoder::ComponentOuterAliasKind::CoreModule,
208            OuterAliasKind::CoreType => wasm_encoder::ComponentOuterAliasKind::CoreType,
209            OuterAliasKind::Type => wasm_encoder::ComponentOuterAliasKind::Type,
210            OuterAliasKind::Component => wasm_encoder::ComponentOuterAliasKind::Component,
211        }
212    }
213}
214
215impl From<&ExportKind> for wasm_encoder::ExportKind {
216    fn from(value: &ExportKind) -> Self {
217        match value {
218            ExportKind::Func => wasm_encoder::ExportKind::Func,
219            ExportKind::Table => wasm_encoder::ExportKind::Table,
220            ExportKind::Mem => wasm_encoder::ExportKind::Memory,
221            ExportKind::Global => wasm_encoder::ExportKind::Global,
222        }
223    }
224}
225
226impl<'a> From<&'a Alias> for wasm_encoder::Alias<'a> {
227    fn from(value: &'a Alias) -> Self {
228        match value {
229            Alias::InstanceExport {
230                kind,
231                instance_idx,
232                name,
233            } => wasm_encoder::Alias::InstanceExport {
234                instance: *instance_idx,
235                kind: kind.into(),
236                name: name.as_str(),
237            },
238            Alias::CoreInstanceExport {
239                kind,
240                instance_idx,
241                name,
242            } => wasm_encoder::Alias::CoreInstanceExport {
243                instance: *instance_idx,
244                kind: kind.into(),
245                name: name.as_str(),
246            },
247            Alias::Outer { kind, target } => wasm_encoder::Alias::Outer {
248                count: target.count,
249                kind: kind.into(),
250                index: target.index,
251            },
252        }
253    }
254}
255
256impl From<&Alias> for wasm_encoder::ComponentAliasSection {
257    fn from(value: &Alias) -> Self {
258        let mut section = wasm_encoder::ComponentAliasSection::new();
259        add_to_alias_section(&mut section, value);
260        section
261    }
262}
263
264fn add_to_alias_section(section: &mut wasm_encoder::ComponentAliasSection, value: &Alias) {
265    section.alias(value.into());
266}
267
268impl TryFrom<&ComponentType> for wasm_encoder::ComponentTypeSection {
269    type Error = String;
270
271    fn try_from(value: &ComponentType) -> Result<Self, Self::Error> {
272        let mut section = wasm_encoder::ComponentTypeSection::new();
273        add_to_type_section(&mut section, value)?;
274        Ok(section)
275    }
276}
277
278impl From<&TypeBounds> for wasm_encoder::TypeBounds {
279    fn from(value: &TypeBounds) -> Self {
280        match value {
281            TypeBounds::Eq(component_type_idx) => wasm_encoder::TypeBounds::Eq(*component_type_idx),
282            TypeBounds::SubResource => wasm_encoder::TypeBounds::SubResource,
283        }
284    }
285}
286
287impl From<&ComponentTypeRef> for wasm_encoder::ComponentTypeRef {
288    fn from(value: &ComponentTypeRef) -> Self {
289        match value {
290            ComponentTypeRef::Module(component_type_idx) => {
291                wasm_encoder::ComponentTypeRef::Module(*component_type_idx)
292            }
293            ComponentTypeRef::Func(component_type_idx) => {
294                wasm_encoder::ComponentTypeRef::Func(*component_type_idx)
295            }
296            ComponentTypeRef::Val(component_val_type) => {
297                wasm_encoder::ComponentTypeRef::Value(component_val_type.into())
298            }
299            ComponentTypeRef::Type(type_bounds) => {
300                wasm_encoder::ComponentTypeRef::Type(type_bounds.into())
301            }
302            ComponentTypeRef::Instance(component_type_idx) => {
303                wasm_encoder::ComponentTypeRef::Instance(*component_type_idx)
304            }
305            ComponentTypeRef::Component(component_type_idx) => {
306                wasm_encoder::ComponentTypeRef::Component(*component_type_idx)
307            }
308        }
309    }
310}
311
312fn add_declaration_to_component_type(
313    component_type: &mut wasm_encoder::ComponentType,
314    value: &ComponentTypeDeclaration,
315) -> Result<(), String> {
316    match value {
317        ComponentTypeDeclaration::Core(core_type) => {
318            add_to_core_type_encoder(component_type.core_type(), core_type)?;
319        }
320        ComponentTypeDeclaration::Type(ct) => {
321            add_to_component_type(component_type.ty(), ct)?;
322        }
323        ComponentTypeDeclaration::Alias(alias) => {
324            component_type.alias(alias.into());
325        }
326        ComponentTypeDeclaration::Import(import) => {
327            component_type.import((&import.name).into(), (&import.desc).into());
328        }
329        ComponentTypeDeclaration::Export { name, desc } => {
330            component_type.export(name.into(), desc.into());
331        }
332    }
333    Ok(())
334}
335
336fn add_declaration_to_instance_type(
337    instance_type: &mut wasm_encoder::InstanceType,
338    value: &InstanceTypeDeclaration,
339) -> Result<(), String> {
340    match value {
341        InstanceTypeDeclaration::Core(core_type) => {
342            add_to_core_type_encoder(instance_type.core_type(), core_type)?;
343        }
344        InstanceTypeDeclaration::Type(ct) => {
345            add_to_component_type(instance_type.ty(), ct)?;
346        }
347        InstanceTypeDeclaration::Alias(alias) => {
348            instance_type.alias(alias.into());
349        }
350        InstanceTypeDeclaration::Export { name, desc } => {
351            instance_type.export(name.into(), desc.into());
352        }
353    }
354    Ok(())
355}
356
357fn add_to_component_type(
358    encoder: wasm_encoder::ComponentTypeEncoder,
359    value: &ComponentType,
360) -> Result<(), String> {
361    match value {
362        ComponentType::Defined(component_defined_type) => {
363            let defined_type = encoder.defined_type();
364            add_to_defined_type(defined_type, component_defined_type);
365        }
366        ComponentType::Func(component_func_type) => {
367            let mut function = encoder.function();
368            function.params(
369                component_func_type
370                    .params
371                    .iter()
372                    .map(|(name, val_type)| (name.as_str(), val_type)),
373            );
374            function.result(component_func_type.result.as_ref().map(|tpe| tpe.into()));
375        }
376        ComponentType::Component(component_type_declarations) => {
377            let mut component_type = wasm_encoder::ComponentType::new();
378            for component_type_declaration in &component_type_declarations.0 {
379                add_declaration_to_component_type(&mut component_type, component_type_declaration)?;
380            }
381            encoder.component(&component_type);
382        }
383        ComponentType::Instance(instance_type_declarations) => {
384            let mut instance_type = wasm_encoder::InstanceType::new();
385            for instance_type_declaration in &instance_type_declarations.0 {
386                add_declaration_to_instance_type(&mut instance_type, instance_type_declaration)?;
387            }
388            encoder.instance(&instance_type);
389        }
390        ComponentType::Resource {
391            representation,
392            destructor,
393        } => encoder.resource(representation.into(), *destructor),
394    }
395    Ok(())
396}
397
398fn add_to_type_section(
399    section: &mut wasm_encoder::ComponentTypeSection,
400    value: &ComponentType,
401) -> Result<(), String> {
402    add_to_component_type(section.ty(), value)
403}
404
405impl From<&PrimitiveValueType> for wasm_encoder::PrimitiveValType {
406    fn from(value: &PrimitiveValueType) -> Self {
407        match value {
408            PrimitiveValueType::Bool => wasm_encoder::PrimitiveValType::Bool,
409            PrimitiveValueType::S8 => wasm_encoder::PrimitiveValType::S8,
410            PrimitiveValueType::U8 => wasm_encoder::PrimitiveValType::U8,
411            PrimitiveValueType::S16 => wasm_encoder::PrimitiveValType::S16,
412            PrimitiveValueType::U16 => wasm_encoder::PrimitiveValType::U16,
413            PrimitiveValueType::S32 => wasm_encoder::PrimitiveValType::S32,
414            PrimitiveValueType::U32 => wasm_encoder::PrimitiveValType::U32,
415            PrimitiveValueType::S64 => wasm_encoder::PrimitiveValType::S64,
416            PrimitiveValueType::U64 => wasm_encoder::PrimitiveValType::U64,
417            PrimitiveValueType::F32 => wasm_encoder::PrimitiveValType::F32,
418            PrimitiveValueType::F64 => wasm_encoder::PrimitiveValType::F64,
419            PrimitiveValueType::Chr => wasm_encoder::PrimitiveValType::Char,
420            PrimitiveValueType::Str => wasm_encoder::PrimitiveValType::String,
421            PrimitiveValueType::ErrorContext => wasm_encoder::PrimitiveValType::ErrorContext,
422        }
423    }
424}
425
426impl From<&ComponentValType> for wasm_encoder::ComponentValType {
427    fn from(value: &ComponentValType) -> Self {
428        match value {
429            ComponentValType::Primitive(primitive_value_type) => {
430                wasm_encoder::ComponentValType::Primitive(primitive_value_type.into())
431            }
432            ComponentValType::Defined(component_type_idx) => {
433                wasm_encoder::ComponentValType::Type(*component_type_idx)
434            }
435        }
436    }
437}
438
439impl<'a> From<&'a VariantCase> for (&'a str, Option<wasm_encoder::ComponentValType>, Option<u32>) {
440    fn from(value: &'a VariantCase) -> Self {
441        (
442            &value.name,
443            value.typ.as_ref().map(|t| t.into()),
444            value.refines,
445        )
446    }
447}
448
449fn add_to_defined_type(
450    defined_type: wasm_encoder::ComponentDefinedTypeEncoder,
451    value: &ComponentDefinedType,
452) {
453    match value {
454        ComponentDefinedType::Primitive { typ } => {
455            defined_type.primitive(typ.into());
456        }
457        ComponentDefinedType::Record { fields } => {
458            defined_type.record(fields.iter().map(|(name, typ)| (name.as_str(), typ)));
459        }
460        ComponentDefinedType::Variant { cases } => {
461            defined_type.variant(cases.iter().map(|case| case.into()));
462        }
463        ComponentDefinedType::List { elem } => {
464            defined_type.list(elem);
465        }
466        ComponentDefinedType::Tuple { elems } => {
467            defined_type.tuple(elems.iter());
468        }
469        ComponentDefinedType::Flags { names } => {
470            defined_type.flags(names.iter().map(|name| name.as_str()));
471        }
472        ComponentDefinedType::Enum { names } => {
473            defined_type.enum_type(names.iter().map(|name| name.as_str()));
474        }
475        ComponentDefinedType::Option { typ } => {
476            defined_type.option(typ);
477        }
478        ComponentDefinedType::Result { ok, err } => {
479            defined_type.result(
480                ok.as_ref().map(|t| t.into()),
481                err.as_ref().map(|t| t.into()),
482            );
483        }
484        ComponentDefinedType::Owned { type_idx } => {
485            defined_type.own(*type_idx);
486        }
487        ComponentDefinedType::Borrowed { type_idx } => {
488            defined_type.borrow(*type_idx);
489        }
490        ComponentDefinedType::Future { inner } => {
491            defined_type.future(inner.as_ref().map(|t| t.into()));
492        }
493        ComponentDefinedType::Stream { inner } => {
494            defined_type.stream(inner.as_ref().map(|t| t.into()));
495        }
496    };
497}
498
499impl From<&Canon> for wasm_encoder::CanonicalFunctionSection {
500    fn from(value: &Canon) -> Self {
501        let mut section = wasm_encoder::CanonicalFunctionSection::new();
502        add_to_canonical_function_section(&mut section, value);
503        section
504    }
505}
506
507impl From<&CanonicalOption> for wasm_encoder::CanonicalOption {
508    fn from(value: &CanonicalOption) -> Self {
509        match value {
510            CanonicalOption::Utf8 => wasm_encoder::CanonicalOption::UTF8,
511            CanonicalOption::Utf16 => wasm_encoder::CanonicalOption::UTF16,
512            CanonicalOption::CompactUtf16 => wasm_encoder::CanonicalOption::CompactUTF16,
513            CanonicalOption::Memory(mem_idx) => wasm_encoder::CanonicalOption::Memory(*mem_idx),
514            CanonicalOption::Realloc(func_idx) => wasm_encoder::CanonicalOption::Realloc(*func_idx),
515            CanonicalOption::PostReturn(func_idx) => {
516                wasm_encoder::CanonicalOption::PostReturn(*func_idx)
517            }
518            CanonicalOption::Async => wasm_encoder::CanonicalOption::Async,
519            CanonicalOption::Callback(func_idx) => {
520                wasm_encoder::CanonicalOption::Callback(*func_idx)
521            }
522        }
523    }
524}
525
526fn add_to_canonical_function_section(
527    section: &mut wasm_encoder::CanonicalFunctionSection,
528    value: &Canon,
529) {
530    match value {
531        Canon::Lift {
532            func_idx,
533            opts,
534            function_type,
535        } => {
536            section.lift(*func_idx, *function_type, opts.iter().map(|opt| opt.into()));
537        }
538        Canon::Lower { func_idx, opts } => {
539            section.lower(*func_idx, opts.iter().map(|opt| opt.into()));
540        }
541        Canon::ResourceNew { type_idx } => {
542            section.resource_new(*type_idx);
543        }
544        Canon::ResourceDrop { type_idx } => {
545            section.resource_drop(*type_idx);
546        }
547        Canon::ResourceRep { type_idx } => {
548            section.resource_rep(*type_idx);
549        }
550    }
551}
552
553impl From<&ComponentImport> for wasm_encoder::ComponentImportSection {
554    fn from(value: &ComponentImport) -> Self {
555        let mut section = wasm_encoder::ComponentImportSection::new();
556        add_to_component_import_section(&mut section, value);
557        section
558    }
559}
560
561fn add_to_component_import_section(
562    section: &mut wasm_encoder::ComponentImportSection,
563    value: &ComponentImport,
564) {
565    section.import((&value.name).into(), (&value.desc).into());
566}
567
568impl From<&ComponentExport> for wasm_encoder::ComponentExportSection {
569    fn from(value: &ComponentExport) -> Self {
570        let mut section = wasm_encoder::ComponentExportSection::new();
571        add_to_component_export_section(&mut section, value);
572        section
573    }
574}
575
576fn add_to_component_export_section(
577    section: &mut wasm_encoder::ComponentExportSection,
578    value: &ComponentExport,
579) {
580    section.export(
581        (&value.name).into(),
582        (&value.kind).into(),
583        value.idx,
584        value.desc.as_ref().map(|type_ref| type_ref.into()),
585    );
586}
587
588impl<Ast> TryFrom<Component<Ast>> for wasm_encoder::Component
589where
590    Ast: AstCustomization,
591    Ast::Expr: RetainsInstructions,
592    Ast::Data: Into<Data<Ast::Expr>>,
593    Ast::Custom: Into<Custom>,
594{
595    type Error = String;
596
597    fn try_from(value: Component<Ast>) -> Result<Self, Self::Error> {
598        let mut component = wasm_encoder::Component::new();
599
600        for (section_type, sections) in value.into_grouped() {
601            match section_type {
602                ComponentSectionType::Module => {
603                    let inner_module = sections.first().unwrap().as_module();
604                    let encoded_module = wasm_encoder::Module::try_from(inner_module.clone())?;
605                    let nested_module = wasm_encoder::ModuleSection(&encoded_module);
606                    component.section(&nested_module);
607                }
608                ComponentSectionType::CoreInstance => {
609                    let mut section = wasm_encoder::InstanceSection::new();
610                    for core_instance in sections {
611                        add_to_core_instance_section(
612                            &mut section,
613                            core_instance.as_core_instance(),
614                        );
615                    }
616                    component.section(&section);
617                }
618                ComponentSectionType::CoreType => {
619                    let mut section = wasm_encoder::CoreTypeSection::new();
620                    for core_type in sections {
621                        add_to_core_type_section(&mut section, core_type.as_core_type())?;
622                    }
623                    component.section(&section);
624                }
625                ComponentSectionType::Component => {
626                    let inner_component = sections.first().unwrap().as_component();
627                    let encoded_component =
628                        wasm_encoder::Component::try_from(inner_component.clone())?;
629                    let nested_component = wasm_encoder::NestedComponentSection(&encoded_component);
630                    component.section(&nested_component);
631                }
632                ComponentSectionType::Instance => {
633                    let mut section = wasm_encoder::ComponentInstanceSection::new();
634                    for component_instance in sections {
635                        add_to_component_instance_section(
636                            &mut section,
637                            component_instance.as_instance(),
638                        );
639                    }
640                    component.section(&section);
641                }
642                ComponentSectionType::Alias => {
643                    let mut section = wasm_encoder::ComponentAliasSection::new();
644                    for alias in sections {
645                        add_to_alias_section(&mut section, alias.as_alias());
646                    }
647                    component.section(&section);
648                }
649                ComponentSectionType::Type => {
650                    let mut section = wasm_encoder::ComponentTypeSection::new();
651                    for typ in sections {
652                        add_to_type_section(&mut section, typ.as_type())?;
653                    }
654                    component.section(&section);
655                }
656                ComponentSectionType::Canon => {
657                    let mut section = wasm_encoder::CanonicalFunctionSection::new();
658                    for canon in sections {
659                        add_to_canonical_function_section(&mut section, canon.as_canon());
660                    }
661                    component.section(&section);
662                }
663                ComponentSectionType::Start => {
664                    let start = sections.first().unwrap().as_start();
665                    let section = wasm_encoder::ComponentStartSection {
666                        function_index: start.func_idx,
667                        args: start.args.clone(),
668                        results: start.results,
669                    };
670                    component.section(&section);
671                }
672                ComponentSectionType::Import => {
673                    let mut section = wasm_encoder::ComponentImportSection::new();
674                    for import in sections {
675                        add_to_component_import_section(&mut section, import.as_import());
676                    }
677                    component.section(&section);
678                }
679                ComponentSectionType::Export => {
680                    let mut section = wasm_encoder::ComponentExportSection::new();
681                    for export in sections {
682                        add_to_component_export_section(&mut section, export.as_export());
683                    }
684                    component.section(&section);
685                }
686                ComponentSectionType::Custom => {
687                    let custom = sections.first().unwrap().as_custom();
688                    let custom: Custom = custom.clone().into();
689                    let section: wasm_encoder::CustomSection = custom.into();
690                    component.section(&section);
691                }
692            }
693        }
694
695        Ok(component)
696    }
697}