wit_bindgen_gen_guest_c/
lib.rs

1mod component_type_object;
2
3use heck::*;
4use std::collections::{BTreeSet, HashMap, HashSet};
5use std::fmt::Write;
6use std::mem;
7use wit_bindgen_core::wit_parser::abi::{
8    AbiVariant, Bindgen, Bitcast, Instruction, LiftLower, WasmType,
9};
10use wit_bindgen_core::{
11    uwrite, uwriteln, wit_parser::*, Files, InterfaceGenerator as _, Ns, WorldGenerator,
12};
13use wit_component::StringEncoding;
14
15#[derive(Default)]
16struct C {
17    src: Source,
18    opts: Opts,
19    includes: Vec<String>,
20    return_pointer_area_size: usize,
21    return_pointer_area_align: usize,
22    names: Ns,
23    needs_string: bool,
24    world: String,
25    sizes: SizeAlign,
26    interface_names: HashMap<InterfaceId, String>,
27}
28
29#[derive(Default, Debug, Clone)]
30#[cfg_attr(feature = "clap", derive(clap::Args))]
31pub struct Opts {
32    /// Skip emitting component allocation helper functions
33    #[cfg_attr(feature = "clap", arg(long))]
34    pub no_helpers: bool,
35    /// Set component string encoding
36    #[cfg_attr(feature = "clap", arg(long, default_value_t = StringEncoding::default()))]
37    pub string_encoding: StringEncoding,
38}
39
40impl Opts {
41    pub fn build(&self) -> Box<dyn WorldGenerator> {
42        let mut r = C::default();
43        r.opts = self.clone();
44        Box::new(r)
45    }
46}
47
48#[derive(Debug, Default)]
49struct Return {
50    scalar: Option<Scalar>,
51    retptrs: Vec<Type>,
52}
53
54struct CSig {
55    name: String,
56    sig: String,
57    params: Vec<(bool, String)>,
58    ret: Return,
59    retptrs: Vec<String>,
60}
61
62#[derive(Debug)]
63enum Scalar {
64    Void,
65    OptionBool(Type),
66    ResultBool(Option<Type>, Option<Type>),
67    Type(Type),
68}
69
70impl WorldGenerator for C {
71    fn preprocess(&mut self, resolve: &Resolve, world: WorldId) {
72        let name = &resolve.worlds[world].name;
73        self.world = name.to_string();
74        self.sizes.fill(resolve);
75    }
76
77    fn import_interface(
78        &mut self,
79        resolve: &Resolve,
80        name: &str,
81        id: InterfaceId,
82        _files: &mut Files,
83    ) {
84        let prev = self.interface_names.insert(id, name.to_string());
85        assert!(prev.is_none());
86        let mut gen = self.interface(name, resolve, true);
87        gen.interface = Some(id);
88        gen.types(id);
89
90        for (i, (_name, func)) in resolve.interfaces[id].functions.iter().enumerate() {
91            if i == 0 {
92                uwriteln!(gen.src.h_fns, "\n// Imported Functions from `{name}`");
93            }
94            gen.import(name, func);
95        }
96
97        gen.finish();
98
99        gen.gen.src.append(&gen.src);
100    }
101
102    fn import_funcs(
103        &mut self,
104        resolve: &Resolve,
105        world: WorldId,
106        funcs: &[(&str, &Function)],
107        _files: &mut Files,
108    ) {
109        let name = &resolve.worlds[world].name;
110        let mut gen = self.interface(name, resolve, true);
111
112        for (i, (_name, func)) in funcs.iter().enumerate() {
113            if i == 0 {
114                uwriteln!(gen.src.h_fns, "\n// Imported Functions from `{name}`");
115            }
116            gen.import("$root", func);
117        }
118
119        gen.finish();
120
121        gen.gen.src.append(&gen.src);
122    }
123
124    fn export_interface(
125        &mut self,
126        resolve: &Resolve,
127        name: &str,
128        id: InterfaceId,
129        _files: &mut Files,
130    ) {
131        self.interface_names.insert(id, name.to_string());
132        let mut gen = self.interface(name, resolve, false);
133        gen.interface = Some(id);
134        gen.types(id);
135
136        for (i, (_name, func)) in resolve.interfaces[id].functions.iter().enumerate() {
137            if i == 0 {
138                uwriteln!(gen.src.h_fns, "\n// Exported Functions from `{name}`");
139            }
140            gen.export(func, Some(name));
141        }
142
143        gen.finish();
144
145        gen.gen.src.append(&gen.src);
146    }
147
148    fn export_funcs(
149        &mut self,
150        resolve: &Resolve,
151        world: WorldId,
152        funcs: &[(&str, &Function)],
153        _files: &mut Files,
154    ) {
155        let name = &resolve.worlds[world].name;
156        let mut gen = self.interface(name, resolve, false);
157
158        for (i, (_name, func)) in funcs.iter().enumerate() {
159            if i == 0 {
160                uwriteln!(gen.src.h_fns, "\n// Exported Functions from `{name}`");
161            }
162            gen.export(func, None);
163        }
164
165        gen.finish();
166
167        gen.gen.src.append(&gen.src);
168    }
169
170    fn export_types(
171        &mut self,
172        resolve: &Resolve,
173        world: WorldId,
174        types: &[(&str, TypeId)],
175        _files: &mut Files,
176    ) {
177        let name = &resolve.worlds[world].name;
178        let mut gen = self.interface(name, resolve, false);
179        for (name, id) in types {
180            gen.define_type(name, *id);
181        }
182        gen.finish();
183        gen.gen.src.append(&gen.src);
184    }
185
186    fn finish(&mut self, resolve: &Resolve, id: WorldId, files: &mut Files) {
187        let world = &resolve.worlds[id];
188        let linking_symbol = component_type_object::linking_symbol(&world.name);
189        self.include("<stdlib.h>");
190        let snake = world.name.to_snake_case();
191        uwrite!(
192            self.src.c_adapters,
193            "
194               extern void {linking_symbol}(void);
195               void {linking_symbol}_public_use_in_this_compilation_unit(void) {{
196                   {linking_symbol}();
197               }}
198           ",
199        );
200
201        self.print_intrinsics();
202
203        if self.needs_string {
204            self.include("<string.h>");
205            let (strlen, size) = match self.opts.string_encoding {
206                StringEncoding::UTF8 => (format!("strlen(s)"), 1),
207                StringEncoding::UTF16 => {
208                    self.include("<uchar.h>");
209                    uwrite!(
210                        self.src.h_helpers,
211                        "
212                            size_t {snake}_string_len(const char16_t* s);
213                        ",
214                    );
215                    uwrite!(
216                        self.src.c_helpers,
217                        "
218                            size_t {snake}_string_len(const char16_t* s) {{
219                                char16_t* c = (char16_t*)s;
220                                for (; *c; ++c);
221                                return c-s;
222                            }}
223                        ",
224                    );
225                    (format!("{snake}_string_len(s)"), 2)
226                }
227                StringEncoding::CompactUTF16 => unimplemented!(),
228            };
229            let ty = self.char_type();
230            uwrite!(
231                self.src.h_helpers,
232                "
233                   void {snake}_string_set({snake}_string_t *ret, const {ty} *s);
234                   void {snake}_string_dup({snake}_string_t *ret, const {ty} *s);
235                   void {snake}_string_free({snake}_string_t *ret);\
236               ",
237            );
238            uwrite!(
239                self.src.c_helpers,
240                "
241                   void {snake}_string_set({snake}_string_t *ret, const {ty} *s) {{
242                       ret->ptr = ({ty}*) s;
243                       ret->len = {strlen};
244                   }}
245
246                   void {snake}_string_dup({snake}_string_t *ret, const {ty} *s) {{
247                       ret->len = {strlen};
248                       ret->ptr = cabi_realloc(NULL, 0, {size}, ret->len * {size});
249                       memcpy(ret->ptr, s, ret->len * {size});
250                   }}
251
252                   void {snake}_string_free({snake}_string_t *ret) {{
253                       if (ret->len > 0) {{
254                           free(ret->ptr);
255                       }}
256                       ret->ptr = NULL;
257                       ret->len = 0;
258                   }}
259               ",
260            );
261        }
262
263        let mut h_str = wit_bindgen_core::Source::default();
264
265        uwrite!(
266            h_str,
267            "#ifndef __BINDINGS_{0}_H
268            #define __BINDINGS_{0}_H
269            #ifdef __cplusplus
270            extern \"C\" {{",
271            world.name.to_shouty_snake_case(),
272        );
273
274        // Deindent the extern C { declaration
275        h_str.deindent(1);
276        uwriteln!(h_str, "\n#endif\n");
277
278        self.include("<stdint.h>");
279        self.include("<stdbool.h>");
280
281        for include in self.includes.iter() {
282            uwriteln!(h_str, "#include {include}");
283        }
284
285        let mut c_str = wit_bindgen_core::Source::default();
286        uwriteln!(c_str, "#include \"{snake}.h\"");
287        if c_str.len() > 0 {
288            c_str.push_str("\n");
289        }
290        c_str.push_str(&self.src.c_defs);
291        c_str.push_str(&self.src.c_fns);
292
293        if self.needs_string {
294            uwriteln!(
295                h_str,
296                "
297                typedef struct {{\n\
298                  {ty} *ptr;\n\
299                  size_t len;\n\
300                }} {snake}_string_t;",
301                ty = self.char_type(),
302            );
303        }
304        if self.src.h_defs.len() > 0 {
305            h_str.push_str(&self.src.h_defs);
306        }
307
308        h_str.push_str(&self.src.h_fns);
309
310        if !self.opts.no_helpers && self.src.h_helpers.len() > 0 {
311            uwriteln!(h_str, "\n// Helper Functions");
312            h_str.push_str(&self.src.h_helpers);
313            h_str.push_str("\n");
314        }
315
316        if !self.opts.no_helpers && self.src.c_helpers.len() > 0 {
317            uwriteln!(c_str, "\n// Helper Functions");
318            c_str.push_str(self.src.c_helpers.as_mut_string());
319        }
320
321        uwriteln!(c_str, "\n// Component Adapters");
322
323        // Declare a statically-allocated return area, if needed. We only do
324        // this for export bindings, because import bindings allocate their
325        // return-area on the stack.
326        if self.return_pointer_area_size > 0 {
327            // Automatic indentation avoided due to `extern "C" {` declaration
328            uwrite!(
329                c_str,
330                "
331                __attribute__((aligned({})))
332                static uint8_t RET_AREA[{}];
333                ",
334                self.return_pointer_area_align,
335                self.return_pointer_area_size,
336            );
337        }
338        c_str.push_str(&self.src.c_adapters);
339
340        uwriteln!(
341            h_str,
342            "
343            #ifdef __cplusplus
344            }}
345            #endif
346            #endif"
347        );
348
349        files.push(&format!("{snake}.c"), c_str.as_bytes());
350        files.push(&format!("{snake}.h"), h_str.as_bytes());
351        files.push(
352            &format!("{snake}_component_type.o",),
353            component_type_object::object(resolve, id, self.opts.string_encoding)
354                .unwrap()
355                .as_slice(),
356        );
357    }
358}
359
360impl C {
361    fn interface<'a>(
362        &'a mut self,
363        name: &'a str,
364        resolve: &'a Resolve,
365        in_import: bool,
366    ) -> InterfaceGenerator<'a> {
367        InterfaceGenerator {
368            name,
369            src: Source::default(),
370            gen: self,
371            resolve,
372            interface: None,
373            public_anonymous_types: Default::default(),
374            private_anonymous_types: Default::default(),
375            types: Default::default(),
376            in_import,
377        }
378    }
379
380    fn include(&mut self, s: &str) {
381        self.includes.push(s.to_string());
382    }
383
384    fn char_type(&self) -> &'static str {
385        match self.opts.string_encoding {
386            StringEncoding::UTF8 => "char",
387            StringEncoding::UTF16 => "char16_t",
388            StringEncoding::CompactUTF16 => panic!("Compact UTF16 unsupported"),
389        }
390    }
391}
392
393struct InterfaceGenerator<'a> {
394    name: &'a str,
395    src: Source,
396    in_import: bool,
397    gen: &'a mut C,
398    resolve: &'a Resolve,
399    interface: Option<InterfaceId>,
400
401    // The set of types that are considered public (aka need to be in the
402    // header file) which are anonymous and we're effectively monomorphizing.
403    // This is discovered lazily when printing type names.
404    public_anonymous_types: BTreeSet<TypeId>,
405
406    // This is similar to `public_anonymous_types` where it's discovered
407    // lazily, but the set here are for private types only used in the
408    // implementation of functions. These types go in the implementation file,
409    // not the header file.
410    private_anonymous_types: BTreeSet<TypeId>,
411
412    // Type definitions for the given `TypeId`. This is printed topologically
413    // at the end.
414    types: HashMap<TypeId, wit_bindgen_core::Source>,
415}
416
417impl C {
418    fn print_intrinsics(&mut self) {
419        // Note that these intrinsics are declared as `weak` so they can be
420        // overridden from some other symbol.
421        self.src.c_fns(
422            r#"
423                __attribute__((weak, export_name("cabi_realloc")))
424                void *cabi_realloc(void *ptr, size_t old_size, size_t align, size_t new_size) {
425                    if (new_size == 0) return (void*) align;
426                    void *ret = realloc(ptr, new_size);
427                    if (!ret) abort();
428                    return ret;
429                }
430            "#,
431        );
432    }
433}
434
435impl Return {
436    fn return_single(&mut self, resolve: &Resolve, ty: &Type, orig_ty: &Type) {
437        let id = match ty {
438            Type::Id(id) => *id,
439            Type::String => {
440                self.retptrs.push(*orig_ty);
441                return;
442            }
443            _ => {
444                self.scalar = Some(Scalar::Type(*orig_ty));
445                return;
446            }
447        };
448        match &resolve.types[id].kind {
449            TypeDefKind::Type(t) => return self.return_single(resolve, t, orig_ty),
450
451            // Flags are returned as their bare values, and enums are scalars
452            TypeDefKind::Flags(_) | TypeDefKind::Enum(_) => {
453                self.scalar = Some(Scalar::Type(*orig_ty));
454                return;
455            }
456
457            // Unpack optional returns where a boolean discriminant is
458            // returned and then the actual type returned is returned
459            // through a return pointer.
460            TypeDefKind::Option(ty) => {
461                self.scalar = Some(Scalar::OptionBool(*ty));
462                self.retptrs.push(*ty);
463                return;
464            }
465
466            // Unpack a result as a boolean return type, with two
467            // return pointers for ok and err values
468            TypeDefKind::Result(r) => {
469                if let Some(ok) = r.ok {
470                    self.retptrs.push(ok);
471                }
472                if let Some(err) = r.err {
473                    self.retptrs.push(err);
474                }
475                self.scalar = Some(Scalar::ResultBool(r.ok, r.err));
476                return;
477            }
478
479            // These types are always returned indirectly.
480            TypeDefKind::Tuple(_)
481            | TypeDefKind::Record(_)
482            | TypeDefKind::List(_)
483            | TypeDefKind::Variant(_)
484            | TypeDefKind::Union(_) => {}
485
486            TypeDefKind::Future(_) => todo!("return_single for future"),
487            TypeDefKind::Stream(_) => todo!("return_single for stream"),
488            TypeDefKind::Unknown => unreachable!(),
489        }
490
491        self.retptrs.push(*orig_ty);
492    }
493}
494
495impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
496    fn resolve(&self) -> &'a Resolve {
497        self.resolve
498    }
499
500    fn type_record(&mut self, id: TypeId, name: &str, record: &Record, docs: &Docs) {
501        let prev = mem::take(&mut self.src.h_defs);
502        self.src.h_defs("\n");
503        self.docs(docs);
504        self.src.h_defs("typedef struct {\n");
505        for field in record.fields.iter() {
506            self.print_ty(SourceType::HDefs, &field.ty);
507            self.src.h_defs(" ");
508            self.src.h_defs(&to_c_ident(&field.name));
509            self.src.h_defs(";\n");
510        }
511        self.src.h_defs("} ");
512        self.print_typedef_target(name);
513
514        self.types
515            .insert(id, mem::replace(&mut self.src.h_defs, prev));
516    }
517
518    fn type_tuple(&mut self, id: TypeId, name: &str, tuple: &Tuple, docs: &Docs) {
519        let prev = mem::take(&mut self.src.h_defs);
520        self.src.h_defs("\n");
521        self.docs(docs);
522        self.src.h_defs("typedef struct {\n");
523        for (i, ty) in tuple.types.iter().enumerate() {
524            self.print_ty(SourceType::HDefs, ty);
525            uwriteln!(self.src.h_defs, " f{i};");
526        }
527        self.src.h_defs("} ");
528        self.print_typedef_target(name);
529
530        self.types
531            .insert(id, mem::replace(&mut self.src.h_defs, prev));
532    }
533
534    fn type_flags(&mut self, id: TypeId, name: &str, flags: &Flags, docs: &Docs) {
535        let prev = mem::take(&mut self.src.h_defs);
536        self.src.h_defs("\n");
537        self.docs(docs);
538        self.src.h_defs("typedef ");
539        let repr = flags_repr(flags);
540        self.src.h_defs(int_repr(repr));
541        self.src.h_defs(" ");
542        self.print_typedef_target(name);
543
544        if flags.flags.len() > 0 {
545            self.src.h_defs("\n");
546        }
547        for (i, flag) in flags.flags.iter().enumerate() {
548            uwriteln!(
549                self.src.h_defs,
550                "#define {}_{}_{} (1 << {})",
551                self.name.to_shouty_snake_case(),
552                name.to_shouty_snake_case(),
553                flag.name.to_shouty_snake_case(),
554                i,
555            );
556        }
557
558        self.types
559            .insert(id, mem::replace(&mut self.src.h_defs, prev));
560    }
561
562    fn type_variant(&mut self, id: TypeId, name: &str, variant: &Variant, docs: &Docs) {
563        let prev = mem::take(&mut self.src.h_defs);
564        self.src.h_defs("\n");
565        self.docs(docs);
566        self.src.h_defs("typedef struct {\n");
567        self.src.h_defs(int_repr(variant.tag()));
568        self.src.h_defs(" tag;\n");
569        self.src.h_defs("union {\n");
570        for case in variant.cases.iter() {
571            if let Some(ty) = self.get_nonempty_type(case.ty.as_ref()) {
572                self.print_ty(SourceType::HDefs, ty);
573                self.src.h_defs(" ");
574                self.src.h_defs(&to_c_ident(&case.name));
575                self.src.h_defs(";\n");
576            }
577        }
578        self.src.h_defs("} val;\n");
579        self.src.h_defs("} ");
580        self.print_typedef_target(name);
581
582        if variant.cases.len() > 0 {
583            self.src.h_defs("\n");
584        }
585        for (i, case) in variant.cases.iter().enumerate() {
586            uwriteln!(
587                self.src.h_defs,
588                "#define {}_{}_{} {}",
589                self.name.to_shouty_snake_case(),
590                name.to_shouty_snake_case(),
591                case.name.to_shouty_snake_case(),
592                i,
593            );
594        }
595
596        self.types
597            .insert(id, mem::replace(&mut self.src.h_defs, prev));
598    }
599
600    fn type_union(&mut self, id: TypeId, name: &str, union: &Union, docs: &Docs) {
601        let prev = mem::take(&mut self.src.h_defs);
602        self.src.h_defs("\n");
603        self.docs(docs);
604        self.src.h_defs("typedef struct {\n");
605        self.src.h_defs(int_repr(union.tag()));
606        self.src.h_defs(" tag;\n");
607        self.src.h_defs("union {\n");
608        for (i, case) in union.cases.iter().enumerate() {
609            self.print_ty(SourceType::HDefs, &case.ty);
610            uwriteln!(self.src.h_defs, " f{i};");
611        }
612        self.src.h_defs("} val;\n");
613        self.src.h_defs("} ");
614        self.print_typedef_target(name);
615
616        self.types
617            .insert(id, mem::replace(&mut self.src.h_defs, prev));
618    }
619
620    fn type_option(&mut self, id: TypeId, name: &str, payload: &Type, docs: &Docs) {
621        let prev = mem::take(&mut self.src.h_defs);
622        self.src.h_defs("\n");
623        self.docs(docs);
624        self.src.h_defs("typedef struct {\n");
625        self.src.h_defs("bool is_some;\n");
626        if !self.is_empty_type(payload) {
627            self.print_ty(SourceType::HDefs, payload);
628            self.src.h_defs(" val;\n");
629        }
630        self.src.h_defs("} ");
631        self.print_typedef_target(name);
632
633        self.types
634            .insert(id, mem::replace(&mut self.src.h_defs, prev));
635    }
636
637    fn type_result(&mut self, id: TypeId, name: &str, result: &Result_, docs: &Docs) {
638        let prev = mem::take(&mut self.src.h_defs);
639        self.src.h_defs("\n");
640        self.docs(docs);
641        self.src.h_defs("typedef struct {\n");
642        self.src.h_defs("bool is_err;\n");
643        self.src.h_defs("union {\n");
644        if let Some(ok) = self.get_nonempty_type(result.ok.as_ref()) {
645            self.print_ty(SourceType::HDefs, ok);
646            self.src.h_defs(" ok;\n");
647        }
648        if let Some(err) = self.get_nonempty_type(result.err.as_ref()) {
649            self.print_ty(SourceType::HDefs, err);
650            self.src.h_defs(" err;\n");
651        }
652        self.src.h_defs("} val;\n");
653        self.src.h_defs("} ");
654        self.print_typedef_target(name);
655
656        self.types
657            .insert(id, mem::replace(&mut self.src.h_defs, prev));
658    }
659
660    fn type_enum(&mut self, id: TypeId, name: &str, enum_: &Enum, docs: &Docs) {
661        let prev = mem::take(&mut self.src.h_defs);
662        uwrite!(self.src.h_defs, "\n");
663        self.docs(docs);
664        let int_t = int_repr(enum_.tag());
665        uwrite!(self.src.h_defs, "typedef {int_t} ");
666        self.print_typedef_target(name);
667
668        if enum_.cases.len() > 0 {
669            self.src.h_defs("\n");
670        }
671        for (i, case) in enum_.cases.iter().enumerate() {
672            uwriteln!(
673                self.src.h_defs,
674                "#define {}_{}_{} {}",
675                self.name.to_shouty_snake_case(),
676                name.to_shouty_snake_case(),
677                case.name.to_shouty_snake_case(),
678                i,
679            );
680        }
681
682        self.types
683            .insert(id, mem::replace(&mut self.src.h_defs, prev));
684    }
685
686    fn type_alias(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
687        let prev = mem::take(&mut self.src.h_defs);
688        self.src.h_defs("\n");
689        self.docs(docs);
690        self.src.h_defs("typedef ");
691        self.print_ty(SourceType::HDefs, ty);
692        self.src.h_defs(" ");
693        self.print_typedef_target(name);
694        self.types
695            .insert(id, mem::replace(&mut self.src.h_defs, prev));
696    }
697
698    fn type_list(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
699        let prev = mem::take(&mut self.src.h_defs);
700        self.src.h_defs("\n");
701        self.docs(docs);
702        self.src.h_defs("typedef struct {\n");
703        self.print_ty(SourceType::HDefs, ty);
704        self.src.h_defs(" *ptr;\n");
705        self.src.h_defs("size_t len;\n");
706        self.src.h_defs("} ");
707        self.print_typedef_target(name);
708        self.types
709            .insert(id, mem::replace(&mut self.src.h_defs, prev));
710    }
711
712    fn type_builtin(&mut self, _id: TypeId, name: &str, ty: &Type, docs: &Docs) {
713        drop((_id, name, ty, docs));
714    }
715}
716
717impl InterfaceGenerator<'_> {
718    fn import(&mut self, wasm_import_module: &str, func: &Function) {
719        let sig = self.resolve.wasm_signature(AbiVariant::GuestImport, func);
720
721        self.src.c_fns("\n");
722
723        // In the private C file, print a function declaration which is the
724        // actual wasm import that we'll be calling, and this has the raw wasm
725        // signature.
726        uwriteln!(
727            self.src.c_fns,
728            "__attribute__((import_module(\"{}\"), import_name(\"{}\")))",
729            wasm_import_module,
730            func.name
731        );
732        let import_name = self.gen.names.tmp(&format!(
733            "__wasm_import_{}_{}",
734            self.name.to_snake_case(),
735            func.name.to_snake_case()
736        ));
737        match sig.results.len() {
738            0 => self.src.c_fns("void"),
739            1 => self.src.c_fns(wasm_type(sig.results[0])),
740            _ => unimplemented!("multi-value return not supported"),
741        }
742        self.src.c_fns(" ");
743        self.src.c_fns(&import_name);
744        self.src.c_fns("(");
745        for (i, param) in sig.params.iter().enumerate() {
746            if i > 0 {
747                self.src.c_fns(", ");
748            }
749            self.src.c_fns(wasm_type(*param));
750        }
751        if sig.params.len() == 0 {
752            self.src.c_fns("void");
753        }
754        self.src.c_fns(");\n");
755
756        // Print the public facing signature into the header, and since that's
757        // what we are defining also print it into the C file.
758        let c_sig = self.print_sig(func);
759        self.src.c_adapters("\n");
760        self.src.c_adapters(&c_sig.sig);
761        self.src.c_adapters(" {\n");
762
763        // construct optional adapters from maybe pointers to real optional
764        // structs internally
765        let mut optional_adapters = String::from("");
766        for (i, (_, param)) in c_sig.params.iter().enumerate() {
767            let ty = &func.params[i].1;
768            if let Type::Id(id) = ty {
769                if let TypeDefKind::Option(option_ty) = &self.resolve.types[*id].kind {
770                    let ty = self.type_string(ty);
771                    uwrite!(
772                        optional_adapters,
773                        "{ty} {param};
774                        {param}.is_some = maybe_{param} != NULL;"
775                    );
776                    if !self.is_empty_type(option_ty) {
777                        uwriteln!(
778                            optional_adapters,
779                            "if (maybe_{param}) {{
780                                {param}.val = *maybe_{param};
781                            }}",
782                        );
783                    }
784                }
785            }
786        }
787
788        let mut f = FunctionBindgen::new(self, c_sig, &import_name);
789        for (pointer, param) in f.sig.params.iter() {
790            f.locals.insert(&param).unwrap();
791            if *pointer {
792                f.params.push(format!("*{}", param));
793            } else {
794                f.params.push(param.clone());
795            }
796        }
797        for ptr in f.sig.retptrs.iter() {
798            f.locals.insert(ptr).unwrap();
799        }
800        f.src.push_str(&optional_adapters);
801        f.gen.resolve.call(
802            AbiVariant::GuestImport,
803            LiftLower::LowerArgsLiftResults,
804            func,
805            &mut f,
806        );
807
808        let FunctionBindgen {
809            src,
810            import_return_pointer_area_size,
811            import_return_pointer_area_align,
812            ..
813        } = f;
814
815        if import_return_pointer_area_size > 0 {
816            self.src.c_adapters(&format!(
817                "\
818                    __attribute__((aligned({import_return_pointer_area_align})))
819                    uint8_t ret_area[{import_return_pointer_area_size}];
820                ",
821            ));
822        }
823
824        self.src.c_adapters(&String::from(src));
825        self.src.c_adapters("}\n");
826    }
827
828    fn export(&mut self, func: &Function, interface_name: Option<&str>) {
829        let sig = self.resolve.wasm_signature(AbiVariant::GuestExport, func);
830
831        let export_name = func.core_export_name(interface_name);
832
833        // Print the actual header for this function into the header file, and
834        // it's what we'll be calling.
835        let h_sig = self.print_sig(func);
836
837        // Generate, in the C source file, the raw wasm signature that has the
838        // canonical ABI.
839        uwriteln!(
840            self.src.c_adapters,
841            "\n__attribute__((export_name(\"{export_name}\")))"
842        );
843        let import_name = self.gen.names.tmp(&format!(
844            "__wasm_export_{}_{}",
845            self.name.to_snake_case(),
846            func.name.to_snake_case()
847        ));
848
849        let mut f = FunctionBindgen::new(self, h_sig, &import_name);
850        match sig.results.len() {
851            0 => f.gen.src.c_adapters("void"),
852            1 => f.gen.src.c_adapters(wasm_type(sig.results[0])),
853            _ => unimplemented!("multi-value return not supported"),
854        }
855        f.gen.src.c_adapters(" ");
856        f.gen.src.c_adapters(&import_name);
857        f.gen.src.c_adapters("(");
858        for (i, param) in sig.params.iter().enumerate() {
859            if i > 0 {
860                f.gen.src.c_adapters(", ");
861            }
862            let name = f.locals.tmp("arg");
863            uwrite!(f.gen.src.c_adapters, "{} {}", wasm_type(*param), name);
864            f.params.push(name);
865        }
866        if sig.params.len() == 0 {
867            f.gen.src.c_adapters("void");
868        }
869        f.gen.src.c_adapters(") {\n");
870
871        // Perform all lifting/lowering and append it to our src.
872        f.gen.resolve.call(
873            AbiVariant::GuestExport,
874            LiftLower::LiftArgsLowerResults,
875            func,
876            &mut f,
877        );
878        let FunctionBindgen { src, .. } = f;
879        self.src.c_adapters(&src);
880        self.src.c_adapters("}\n");
881
882        if self.resolve.guest_export_needs_post_return(func) {
883            uwriteln!(
884                self.src.c_fns,
885                "__attribute__((weak, export_name(\"cabi_post_{export_name}\")))"
886            );
887            uwrite!(self.src.c_fns, "void {import_name}_post_return(");
888
889            let mut params = Vec::new();
890            let mut c_sig = CSig {
891                name: String::from("INVALID"),
892                sig: String::from("INVALID"),
893                params: Vec::new(),
894                ret: Return::default(),
895                retptrs: Vec::new(),
896            };
897            for (i, result) in sig.results.iter().enumerate() {
898                let name = format!("arg{i}");
899                uwrite!(self.src.c_fns, "{} {name}", wasm_type(*result));
900                c_sig.params.push((false, name.clone()));
901                params.push(name);
902            }
903            self.src.c_fns.push_str(") {\n");
904
905            let mut f = FunctionBindgen::new(self, c_sig, &import_name);
906            f.params = params;
907            f.gen.resolve.post_return(func, &mut f);
908            let FunctionBindgen { src, .. } = f;
909            self.src.c_fns(&src);
910            self.src.c_fns("}\n");
911        }
912    }
913
914    fn finish(&mut self) {
915        // Continuously generate anonymous types while we continue to find more
916        //
917        // First we take care of the public set of anonymous types. This will
918        // iteratively print them and also remove any references from the
919        // private set if we happen to also reference them.
920        while !self.public_anonymous_types.is_empty() {
921            for ty in mem::take(&mut self.public_anonymous_types) {
922                self.print_anonymous_type(ty);
923            }
924        }
925
926        // Next we take care of private types. To do this we have basically the
927        // same loop as above, after we switch the sets. We record, however,
928        // all private types in a local set here to later determine if the type
929        // needs to be in the C file or the H file.
930        //
931        // Note though that we don't re-print a type (and consider it private)
932        // if we already printed it above as part of the public set.
933        let mut private_types = HashSet::new();
934        self.public_anonymous_types = mem::take(&mut self.private_anonymous_types);
935        while !self.public_anonymous_types.is_empty() {
936            for ty in mem::take(&mut self.public_anonymous_types) {
937                if self.types.contains_key(&ty) {
938                    continue;
939                }
940                private_types.insert(ty);
941                self.print_anonymous_type(ty);
942            }
943        }
944
945        for (id, _) in self.resolve.types.iter() {
946            if let Some(ty) = self.types.get(&id) {
947                if private_types.contains(&id) {
948                    // It's private; print it in the .c file.
949                    self.src.c_defs(ty);
950                } else {
951                    // It's public; print it in the .h file.
952                    self.src.h_defs(ty);
953                    self.print_dtor(id);
954                }
955            }
956        }
957    }
958
959    fn print_sig(&mut self, func: &Function) -> CSig {
960        let name = format!(
961            "{}_{}",
962            self.name.to_snake_case(),
963            func.name.to_snake_case()
964        );
965        self.gen.names.insert(&name).expect("duplicate symbols");
966
967        let start = self.src.h_fns.len();
968        let mut result_rets = false;
969        let mut result_rets_has_ok_type = false;
970
971        let ret = self.classify_ret(func);
972        match &ret.scalar {
973            None | Some(Scalar::Void) => self.src.h_fns("void"),
974            Some(Scalar::OptionBool(_id)) => self.src.h_fns("bool"),
975            Some(Scalar::ResultBool(ok, _err)) => {
976                result_rets = true;
977                result_rets_has_ok_type = ok.is_some();
978                self.src.h_fns("bool");
979            }
980            Some(Scalar::Type(ty)) => self.print_ty(SourceType::HFns, ty),
981        }
982        self.src.h_fns(" ");
983        self.src.h_fns(&name);
984        self.src.h_fns("(");
985        let mut params = Vec::new();
986        for (i, (name, ty)) in func.params.iter().enumerate() {
987            if i > 0 {
988                self.src.h_fns(", ");
989            }
990            let pointer = self.is_arg_by_pointer(ty);
991            // optional param pointer flattening
992            let optional_type = if let Type::Id(id) = ty {
993                if let TypeDefKind::Option(option_ty) = &self.resolve.types[*id].kind {
994                    Some(option_ty)
995                } else {
996                    None
997                }
998            } else {
999                None
1000            };
1001            let (print_ty, print_name) = if let Some(option_ty) = optional_type {
1002                (option_ty, format!("maybe_{}", to_c_ident(name)))
1003            } else {
1004                (ty, to_c_ident(name))
1005            };
1006            self.print_ty(SourceType::HFns, print_ty);
1007            self.src.h_fns(" ");
1008            if pointer {
1009                self.src.h_fns("*");
1010            }
1011            self.src.h_fns(&print_name);
1012            params.push((optional_type.is_none() && pointer, to_c_ident(name)));
1013        }
1014        let mut retptrs = Vec::new();
1015        let single_ret = ret.retptrs.len() == 1;
1016        for (i, ty) in ret.retptrs.iter().enumerate() {
1017            if i > 0 || func.params.len() > 0 {
1018                self.src.h_fns(", ");
1019            }
1020            self.print_ty(SourceType::HFns, ty);
1021            self.src.h_fns(" *");
1022            let name: String = if result_rets {
1023                assert!(i <= 1);
1024                if i == 0 && result_rets_has_ok_type {
1025                    "ret".into()
1026                } else {
1027                    "err".into()
1028                }
1029            } else if single_ret {
1030                "ret".into()
1031            } else {
1032                format!("ret{}", i)
1033            };
1034            self.src.h_fns(&name);
1035            retptrs.push(name);
1036        }
1037        if func.params.len() == 0 && ret.retptrs.len() == 0 {
1038            self.src.h_fns("void");
1039        }
1040        self.src.h_fns(")");
1041
1042        let sig = self.src.h_fns[start..].to_string();
1043        self.src.h_fns(";\n");
1044
1045        CSig {
1046            sig,
1047            name,
1048            params,
1049            ret,
1050            retptrs,
1051        }
1052    }
1053
1054    fn classify_ret(&mut self, func: &Function) -> Return {
1055        let mut ret = Return::default();
1056        match func.results.len() {
1057            0 => ret.scalar = Some(Scalar::Void),
1058            1 => {
1059                let ty = func.results.iter_types().next().unwrap();
1060                ret.return_single(self.resolve, ty, ty);
1061            }
1062            _ => {
1063                ret.retptrs.extend(func.results.iter_types().cloned());
1064            }
1065        }
1066        return ret;
1067    }
1068
1069    fn is_arg_by_pointer(&self, ty: &Type) -> bool {
1070        match ty {
1071            Type::Id(id) => match &self.resolve.types[*id].kind {
1072                TypeDefKind::Type(t) => self.is_arg_by_pointer(t),
1073                TypeDefKind::Variant(_) => true,
1074                TypeDefKind::Union(_) => true,
1075                TypeDefKind::Option(_) => true,
1076                TypeDefKind::Result(_) => true,
1077                TypeDefKind::Enum(_) => false,
1078                TypeDefKind::Flags(_) => false,
1079                TypeDefKind::Tuple(_) | TypeDefKind::Record(_) | TypeDefKind::List(_) => true,
1080                TypeDefKind::Future(_) => todo!("is_arg_by_pointer for future"),
1081                TypeDefKind::Stream(_) => todo!("is_arg_by_pointer for stream"),
1082                TypeDefKind::Unknown => unreachable!(),
1083            },
1084            Type::String => true,
1085            _ => false,
1086        }
1087    }
1088
1089    fn print_typedef_target(&mut self, name: &str) {
1090        let iface_snake = self.name.to_snake_case();
1091        let snake = name.to_snake_case();
1092        self.print_namespace(SourceType::HDefs);
1093        self.src.h_defs(&snake);
1094        self.src.h_defs("_t;\n");
1095        self.gen
1096            .names
1097            .insert(&format!("{iface_snake}_{snake}_t"))
1098            .unwrap();
1099    }
1100
1101    fn print_namespace(&mut self, stype: SourceType) {
1102        self.src.print(stype, &self.name.to_snake_case());
1103        self.src.print(stype, "_");
1104    }
1105
1106    fn print_ty(&mut self, stype: SourceType, ty: &Type) {
1107        match ty {
1108            Type::Bool => self.src.print(stype, "bool"),
1109            Type::Char => self.src.print(stype, "uint32_t"), // TODO: better type?
1110            Type::U8 => self.src.print(stype, "uint8_t"),
1111            Type::S8 => self.src.print(stype, "int8_t"),
1112            Type::U16 => self.src.print(stype, "uint16_t"),
1113            Type::S16 => self.src.print(stype, "int16_t"),
1114            Type::U32 => self.src.print(stype, "uint32_t"),
1115            Type::S32 => self.src.print(stype, "int32_t"),
1116            Type::U64 => self.src.print(stype, "uint64_t"),
1117            Type::S64 => self.src.print(stype, "int64_t"),
1118            Type::Float32 => self.src.print(stype, "float"),
1119            Type::Float64 => self.src.print(stype, "double"),
1120            Type::String => {
1121                self.src.print(stype, &self.gen.world.to_snake_case());
1122                self.src.print(stype, "_");
1123                self.src.print(stype, "string_t");
1124                self.gen.needs_string = true;
1125            }
1126            Type::Id(id) => {
1127                let ty = &self.resolve.types[*id];
1128                match &ty.name {
1129                    Some(name) => {
1130                        match ty.owner {
1131                            TypeOwner::Interface(owner) => {
1132                                self.src.print(
1133                                    stype,
1134                                    &self.gen.interface_names[&owner].to_snake_case(),
1135                                );
1136                                self.src.print(stype, "_");
1137                            }
1138                            TypeOwner::World(owner) => {
1139                                self.src
1140                                    .print(stype, &self.resolve.worlds[owner].name.to_snake_case());
1141                                self.src.print(stype, "_");
1142                            }
1143                            TypeOwner::None => {}
1144                        }
1145
1146                        self.src.print(stype, &name.to_snake_case());
1147                        self.src.print(stype, "_t");
1148                    }
1149                    None => match &ty.kind {
1150                        TypeDefKind::Type(t) => self.print_ty(stype, t),
1151                        _ => {
1152                            self.public_anonymous_types.insert(*id);
1153                            self.private_anonymous_types.remove(id);
1154                            self.print_namespace(stype);
1155                            self.print_ty_name(stype, &Type::Id(*id));
1156                            self.src.print(stype, "_t");
1157                        }
1158                    },
1159                }
1160            }
1161        }
1162    }
1163
1164    fn print_ty_name(&mut self, stype: SourceType, ty: &Type) {
1165        match ty {
1166            Type::Bool => self.src.print(stype, "bool"),
1167            Type::Char => self.src.print(stype, "char32"),
1168            Type::U8 => self.src.print(stype, "u8"),
1169            Type::S8 => self.src.print(stype, "s8"),
1170            Type::U16 => self.src.print(stype, "u16"),
1171            Type::S16 => self.src.print(stype, "s16"),
1172            Type::U32 => self.src.print(stype, "u32"),
1173            Type::S32 => self.src.print(stype, "s32"),
1174            Type::U64 => self.src.print(stype, "u64"),
1175            Type::S64 => self.src.print(stype, "s64"),
1176            Type::Float32 => self.src.print(stype, "float32"),
1177            Type::Float64 => self.src.print(stype, "float64"),
1178            Type::String => self.src.print(stype, "string"),
1179            Type::Id(id) => {
1180                let ty = &self.resolve.types[*id];
1181                if let Some(name) = &ty.name {
1182                    return self.src.print(stype, &name.to_snake_case());
1183                }
1184                match &ty.kind {
1185                    TypeDefKind::Type(t) => self.print_ty_name(stype, t),
1186                    TypeDefKind::Record(_)
1187                    | TypeDefKind::Flags(_)
1188                    | TypeDefKind::Enum(_)
1189                    | TypeDefKind::Variant(_)
1190                    | TypeDefKind::Union(_) => {
1191                        unimplemented!()
1192                    }
1193                    TypeDefKind::Tuple(t) => {
1194                        self.src.print(stype, "tuple");
1195                        self.src.print(stype, &t.types.len().to_string());
1196                        for ty in t.types.iter() {
1197                            self.src.print(stype, "_");
1198                            self.print_ty_name(stype, ty);
1199                        }
1200                    }
1201                    TypeDefKind::Option(ty) => {
1202                        self.src.print(stype, "option_");
1203                        self.print_ty_name(stype, ty);
1204                    }
1205                    TypeDefKind::Result(r) => {
1206                        self.src.print(stype, "result_");
1207                        self.print_optional_ty_name(stype, r.ok.as_ref());
1208                        self.src.print(stype, "_");
1209                        self.print_optional_ty_name(stype, r.err.as_ref());
1210                    }
1211                    TypeDefKind::List(t) => {
1212                        self.src.print(stype, "list_");
1213                        self.print_ty_name(stype, t);
1214                    }
1215                    TypeDefKind::Future(t) => {
1216                        self.src.print(stype, "future_");
1217                        self.print_optional_ty_name(stype, t.as_ref());
1218                    }
1219                    TypeDefKind::Stream(s) => {
1220                        self.src.print(stype, "stream_");
1221                        self.print_optional_ty_name(stype, s.element.as_ref());
1222                        self.src.print(stype, "_");
1223                        self.print_optional_ty_name(stype, s.end.as_ref());
1224                    }
1225                    TypeDefKind::Unknown => unreachable!(),
1226                }
1227            }
1228        }
1229    }
1230
1231    fn print_optional_ty_name(&mut self, stype: SourceType, ty: Option<&Type>) {
1232        match ty {
1233            Some(ty) => self.print_ty_name(stype, ty),
1234            None => self.src.print(stype, "void"),
1235        }
1236    }
1237
1238    fn docs(&mut self, docs: &Docs) {
1239        let docs = match &docs.contents {
1240            Some(docs) => docs,
1241            None => return,
1242        };
1243        for line in docs.trim().lines() {
1244            self.src.h_defs("// ");
1245            self.src.h_defs(line);
1246            self.src.h_defs("\n");
1247        }
1248    }
1249
1250    fn is_empty_type(&self, ty: &Type) -> bool {
1251        let id = match ty {
1252            Type::Id(id) => *id,
1253            _ => return false,
1254        };
1255        match &self.resolve.types[id].kind {
1256            TypeDefKind::Type(t) => self.is_empty_type(t),
1257            TypeDefKind::Record(r) => r.fields.is_empty(),
1258            TypeDefKind::Tuple(t) => t.types.is_empty(),
1259            _ => false,
1260        }
1261    }
1262
1263    fn get_nonempty_type<'o>(&self, ty: Option<&'o Type>) -> Option<&'o Type> {
1264        match ty {
1265            Some(ty) => {
1266                if self.is_empty_type(ty) {
1267                    None
1268                } else {
1269                    Some(ty)
1270                }
1271            }
1272            None => None,
1273        }
1274    }
1275
1276    fn type_string(&mut self, ty: &Type) -> String {
1277        // Getting a type string happens during codegen, and by default means
1278        // that this is a private type that's being generated. This means we
1279        // want to keep track of new anonymous types that are *only* mentioned
1280        // in methods like this, so we can place those types in the C file
1281        // instead of the header interface file.
1282        let prev = mem::take(&mut self.src.h_defs);
1283        let prev_public = mem::take(&mut self.public_anonymous_types);
1284        let prev_private = mem::take(&mut self.private_anonymous_types);
1285
1286        // Print the type, which will collect into the fields that we replaced
1287        // above.
1288        self.print_ty(SourceType::HDefs, ty);
1289
1290        // Reset our public/private sets back to what they were beforehand.
1291        // Note that `print_ty` always adds to the public set, so we're
1292        // inverting the meaning here by interpreting those as new private
1293        // types.
1294        let new_private = mem::replace(&mut self.public_anonymous_types, prev_public);
1295        assert!(self.private_anonymous_types.is_empty());
1296        self.private_anonymous_types = prev_private;
1297
1298        // For all new private types found while we printed this type, if the
1299        // type isn't already public then it's a new private type.
1300        for id in new_private {
1301            if !self.public_anonymous_types.contains(&id) {
1302                self.private_anonymous_types.insert(id);
1303            }
1304        }
1305
1306        mem::replace(&mut self.src.h_defs, prev).into()
1307    }
1308
1309    fn print_anonymous_type(&mut self, ty: TypeId) {
1310        let prev = mem::take(&mut self.src.h_defs);
1311        self.src.h_defs("\ntypedef ");
1312        let kind = &self.resolve.types[ty].kind;
1313        match kind {
1314            TypeDefKind::Type(_)
1315            | TypeDefKind::Flags(_)
1316            | TypeDefKind::Record(_)
1317            | TypeDefKind::Enum(_)
1318            | TypeDefKind::Variant(_)
1319            | TypeDefKind::Union(_) => {
1320                unreachable!()
1321            }
1322            TypeDefKind::Tuple(t) => {
1323                self.src.h_defs("struct {\n");
1324                for (i, t) in t.types.iter().enumerate() {
1325                    self.print_ty(SourceType::HDefs, t);
1326                    uwriteln!(self.src.h_defs, " f{i};");
1327                }
1328                self.src.h_defs("}");
1329            }
1330            TypeDefKind::Option(t) => {
1331                self.src.h_defs("struct {\n");
1332                self.src.h_defs("bool is_some;\n");
1333                if !self.is_empty_type(t) {
1334                    self.print_ty(SourceType::HDefs, t);
1335                    self.src.h_defs(" val;\n");
1336                }
1337                self.src.h_defs("}");
1338            }
1339            TypeDefKind::Result(r) => {
1340                self.src.h_defs(
1341                    "struct {
1342                    bool is_err;
1343                    union {
1344                ",
1345                );
1346                if let Some(ok) = self.get_nonempty_type(r.ok.as_ref()) {
1347                    self.print_ty(SourceType::HDefs, ok);
1348                    self.src.h_defs(" ok;\n");
1349                }
1350                if let Some(err) = self.get_nonempty_type(r.err.as_ref()) {
1351                    self.print_ty(SourceType::HDefs, err);
1352                    self.src.h_defs(" err;\n");
1353                }
1354                self.src.h_defs("} val;\n");
1355                self.src.h_defs("}");
1356            }
1357            TypeDefKind::List(t) => {
1358                self.src.h_defs("struct {\n");
1359                self.print_ty(SourceType::HDefs, t);
1360                self.src.h_defs(" *ptr;\n");
1361                self.src.h_defs("size_t len;\n");
1362                self.src.h_defs("}");
1363            }
1364            TypeDefKind::Future(_) => todo!("print_anonymous_type for future"),
1365            TypeDefKind::Stream(_) => todo!("print_anonymous_type for stream"),
1366            TypeDefKind::Unknown => unreachable!(),
1367        }
1368        self.src.h_defs(" ");
1369        self.print_namespace(SourceType::HDefs);
1370        self.print_ty_name(SourceType::HDefs, &Type::Id(ty));
1371        self.src.h_defs("_t;\n");
1372        let type_source = mem::replace(&mut self.src.h_defs, prev);
1373        self.types.insert(ty, type_source);
1374    }
1375
1376    fn print_dtor(&mut self, id: TypeId) {
1377        let ty = Type::Id(id);
1378        if !self.owns_anything(&ty) {
1379            return;
1380        }
1381        let pos = self.src.h_helpers.len();
1382        self.src.h_helpers("\nvoid ");
1383        self.print_namespace(SourceType::HHelpers);
1384        self.print_ty_name(SourceType::HHelpers, &ty);
1385        self.src.h_helpers("_free(");
1386        self.print_namespace(SourceType::HHelpers);
1387        self.print_ty_name(SourceType::HHelpers, &ty);
1388        self.src.h_helpers("_t *ptr)");
1389
1390        self.src.c_helpers(&self.src.h_helpers[pos..].to_string());
1391        self.src.h_helpers(";");
1392        self.src.c_helpers(" {\n");
1393        match &self.resolve.types[id].kind {
1394            TypeDefKind::Type(t) => self.free(t, "ptr"),
1395
1396            TypeDefKind::Flags(_) => {}
1397            TypeDefKind::Enum(_) => {}
1398
1399            TypeDefKind::Record(r) => {
1400                for field in r.fields.iter() {
1401                    if !self.owns_anything(&field.ty) {
1402                        continue;
1403                    }
1404                    self.free(&field.ty, &format!("&ptr->{}", to_c_ident(&field.name)));
1405                }
1406            }
1407
1408            TypeDefKind::Tuple(t) => {
1409                for (i, ty) in t.types.iter().enumerate() {
1410                    if !self.owns_anything(ty) {
1411                        continue;
1412                    }
1413                    self.free(ty, &format!("&ptr->f{i}"));
1414                }
1415            }
1416
1417            TypeDefKind::List(t) => {
1418                if self.owns_anything(t) {
1419                    self.src
1420                        .c_helpers("for (size_t i = 0; i < ptr->len; i++) {\n");
1421                    self.free(t, "&ptr->ptr[i]");
1422                    self.src.c_helpers("}\n");
1423                }
1424                uwriteln!(self.src.c_helpers, "if (ptr->len > 0) {{");
1425                uwriteln!(self.src.c_helpers, "free(ptr->ptr);");
1426                uwriteln!(self.src.c_helpers, "}}");
1427            }
1428
1429            TypeDefKind::Variant(v) => {
1430                self.src.c_helpers("switch ((int32_t) ptr->tag) {\n");
1431                for (i, case) in v.cases.iter().enumerate() {
1432                    if let Some(ty) = &case.ty {
1433                        if !self.owns_anything(ty) {
1434                            continue;
1435                        }
1436                        uwriteln!(self.src.c_helpers, "case {}: {{", i);
1437                        let expr = format!("&ptr->val.{}", to_c_ident(&case.name));
1438                        if let Some(ty) = &case.ty {
1439                            self.free(ty, &expr);
1440                        }
1441                        self.src.c_helpers("break;\n");
1442                        self.src.c_helpers("}\n");
1443                    }
1444                }
1445                self.src.c_helpers("}\n");
1446            }
1447
1448            TypeDefKind::Union(u) => {
1449                self.src.c_helpers("switch ((int32_t) ptr->tag) {\n");
1450                for (i, case) in u.cases.iter().enumerate() {
1451                    if !self.owns_anything(&case.ty) {
1452                        continue;
1453                    }
1454                    uwriteln!(self.src.c_helpers, "case {i}: {{");
1455                    let expr = format!("&ptr->val.f{i}");
1456                    self.free(&case.ty, &expr);
1457                    self.src.c_helpers("break;\n");
1458                    self.src.c_helpers("}\n");
1459                }
1460                self.src.c_helpers("}\n");
1461            }
1462
1463            TypeDefKind::Option(t) => {
1464                self.src.c_helpers("if (ptr->is_some) {\n");
1465                self.free(t, "&ptr->val");
1466                self.src.c_helpers("}\n");
1467            }
1468
1469            TypeDefKind::Result(r) => {
1470                self.src.c_helpers("if (!ptr->is_err) {\n");
1471                if let Some(ok) = &r.ok {
1472                    if self.owns_anything(ok) {
1473                        self.free(ok, "&ptr->val.ok");
1474                    }
1475                }
1476                if let Some(err) = &r.err {
1477                    if self.owns_anything(err) {
1478                        self.src.c_helpers("} else {\n");
1479                        self.free(err, "&ptr->val.err");
1480                    }
1481                }
1482                self.src.c_helpers("}\n");
1483            }
1484            TypeDefKind::Future(_) => todo!("print_dtor for future"),
1485            TypeDefKind::Stream(_) => todo!("print_dtor for stream"),
1486            TypeDefKind::Unknown => unreachable!(),
1487        }
1488        self.src.c_helpers("}\n");
1489    }
1490
1491    fn owns_anything(&self, ty: &Type) -> bool {
1492        let id = match ty {
1493            Type::Id(id) => *id,
1494            Type::String => return true,
1495            _ => return false,
1496        };
1497        match &self.resolve.types[id].kind {
1498            TypeDefKind::Type(t) => self.owns_anything(t),
1499            TypeDefKind::Record(r) => r.fields.iter().any(|t| self.owns_anything(&t.ty)),
1500            TypeDefKind::Tuple(t) => t.types.iter().any(|t| self.owns_anything(t)),
1501            TypeDefKind::Flags(_) => false,
1502            TypeDefKind::Enum(_) => false,
1503            TypeDefKind::List(_) => true,
1504            TypeDefKind::Variant(v) => v
1505                .cases
1506                .iter()
1507                .any(|c| self.optional_owns_anything(c.ty.as_ref())),
1508            TypeDefKind::Union(v) => v.cases.iter().any(|case| self.owns_anything(&case.ty)),
1509            TypeDefKind::Option(t) => self.owns_anything(t),
1510            TypeDefKind::Result(r) => {
1511                self.optional_owns_anything(r.ok.as_ref())
1512                    || self.optional_owns_anything(r.err.as_ref())
1513            }
1514            TypeDefKind::Future(_) => todo!("owns_anything for future"),
1515            TypeDefKind::Stream(_) => todo!("owns_anything for stream"),
1516            TypeDefKind::Unknown => unreachable!(),
1517        }
1518    }
1519
1520    fn optional_owns_anything(&self, ty: Option<&Type>) -> bool {
1521        match ty {
1522            Some(ty) => self.owns_anything(ty),
1523            None => false,
1524        }
1525    }
1526
1527    fn free(&mut self, ty: &Type, expr: &str) {
1528        let prev = mem::take(&mut self.src.h_helpers);
1529        match ty {
1530            Type::String => {
1531                self.src.h_helpers(&self.gen.world.to_snake_case());
1532                self.src.h_helpers("_");
1533            }
1534            _ => {
1535                self.print_namespace(SourceType::HHelpers);
1536            }
1537        }
1538        self.print_ty_name(SourceType::HHelpers, ty);
1539        let name = mem::replace(&mut self.src.h_helpers, prev);
1540
1541        self.src.c_helpers(&name);
1542        self.src.c_helpers("_free(");
1543        self.src.c_helpers(expr);
1544        self.src.c_helpers(");\n");
1545    }
1546}
1547
1548struct FunctionBindgen<'a, 'b> {
1549    gen: &'a mut InterfaceGenerator<'b>,
1550    locals: Ns,
1551    src: wit_bindgen_core::Source,
1552    sig: CSig,
1553    func_to_call: &'a str,
1554    block_storage: Vec<wit_bindgen_core::Source>,
1555    blocks: Vec<(String, Vec<String>)>,
1556    payloads: Vec<String>,
1557    params: Vec<String>,
1558    wasm_return: Option<String>,
1559    ret_store_cnt: usize,
1560    import_return_pointer_area_size: usize,
1561    import_return_pointer_area_align: usize,
1562}
1563
1564impl<'a, 'b> FunctionBindgen<'a, 'b> {
1565    fn new(
1566        gen: &'a mut InterfaceGenerator<'b>,
1567        sig: CSig,
1568        func_to_call: &'a str,
1569    ) -> FunctionBindgen<'a, 'b> {
1570        FunctionBindgen {
1571            gen,
1572            sig,
1573            locals: Default::default(),
1574            src: Default::default(),
1575            func_to_call,
1576            block_storage: Vec::new(),
1577            blocks: Vec::new(),
1578            payloads: Vec::new(),
1579            params: Vec::new(),
1580            wasm_return: None,
1581            ret_store_cnt: 0,
1582            import_return_pointer_area_size: 0,
1583            import_return_pointer_area_align: 0,
1584        }
1585    }
1586
1587    fn store_op(&mut self, op: &str, loc: &str) {
1588        self.src.push_str(loc);
1589        self.src.push_str(" = ");
1590        self.src.push_str(op);
1591        self.src.push_str(";\n");
1592    }
1593
1594    fn load(&mut self, ty: &str, offset: i32, operands: &[String], results: &mut Vec<String>) {
1595        results.push(format!("*(({}*) ({} + {}))", ty, operands[0], offset));
1596    }
1597
1598    fn load_ext(&mut self, ty: &str, offset: i32, operands: &[String], results: &mut Vec<String>) {
1599        self.load(ty, offset, operands, results);
1600        let result = results.pop().unwrap();
1601        results.push(format!("(int32_t) ({})", result));
1602    }
1603
1604    fn store(&mut self, ty: &str, offset: i32, operands: &[String]) {
1605        uwriteln!(
1606            self.src,
1607            "*(({}*)({} + {})) = {};",
1608            ty,
1609            operands[1],
1610            offset,
1611            operands[0]
1612        );
1613    }
1614
1615    fn store_in_retptr(&mut self, operand: &String) {
1616        self.store_op(
1617            operand,
1618            &format!("*{}", self.sig.retptrs[self.ret_store_cnt]),
1619        );
1620        self.ret_store_cnt = self.ret_store_cnt + 1;
1621    }
1622}
1623
1624impl Bindgen for FunctionBindgen<'_, '_> {
1625    type Operand = String;
1626
1627    fn sizes(&self) -> &SizeAlign {
1628        &self.gen.gen.sizes
1629    }
1630
1631    fn push_block(&mut self) {
1632        let prev = mem::take(&mut self.src);
1633        self.block_storage.push(prev);
1634    }
1635
1636    fn finish_block(&mut self, operands: &mut Vec<String>) {
1637        let to_restore = self.block_storage.pop().unwrap();
1638        let src = mem::replace(&mut self.src, to_restore);
1639        self.blocks.push((src.into(), mem::take(operands)));
1640    }
1641
1642    fn return_pointer(&mut self, size: usize, align: usize) -> String {
1643        let ptr = self.locals.tmp("ptr");
1644
1645        // Use a stack-based return area for imports, because exports need
1646        // their return area to be live until the post-return call.
1647        if self.gen.in_import {
1648            self.import_return_pointer_area_size = self.import_return_pointer_area_size.max(size);
1649            self.import_return_pointer_area_align =
1650                self.import_return_pointer_area_align.max(align);
1651            uwriteln!(self.src, "int32_t {} = (int32_t) &ret_area;", ptr);
1652        } else {
1653            self.gen.gen.return_pointer_area_size = self.gen.gen.return_pointer_area_size.max(size);
1654            self.gen.gen.return_pointer_area_align =
1655                self.gen.gen.return_pointer_area_align.max(align);
1656            // Declare a statically-allocated return area.
1657            uwriteln!(self.src, "int32_t {} = (int32_t) &RET_AREA;", ptr);
1658        }
1659
1660        ptr
1661    }
1662
1663    fn is_list_canonical(&self, resolve: &Resolve, ty: &Type) -> bool {
1664        resolve.all_bits_valid(ty)
1665    }
1666
1667    fn emit(
1668        &mut self,
1669        _resolve: &Resolve,
1670        inst: &Instruction<'_>,
1671        operands: &mut Vec<String>,
1672        results: &mut Vec<String>,
1673    ) {
1674        match inst {
1675            Instruction::GetArg { nth } => results.push(self.params[*nth].clone()),
1676            Instruction::I32Const { val } => results.push(val.to_string()),
1677            Instruction::ConstZero { tys } => {
1678                for _ in tys.iter() {
1679                    results.push("0".to_string());
1680                }
1681            }
1682
1683            // TODO: checked?
1684            Instruction::U8FromI32 => results.push(format!("(uint8_t) ({})", operands[0])),
1685            Instruction::S8FromI32 => results.push(format!("(int8_t) ({})", operands[0])),
1686            Instruction::U16FromI32 => results.push(format!("(uint16_t) ({})", operands[0])),
1687            Instruction::S16FromI32 => results.push(format!("(int16_t) ({})", operands[0])),
1688            Instruction::U32FromI32 => results.push(format!("(uint32_t) ({})", operands[0])),
1689            Instruction::S32FromI32 | Instruction::S64FromI64 => results.push(operands[0].clone()),
1690            Instruction::U64FromI64 => results.push(format!("(uint64_t) ({})", operands[0])),
1691
1692            Instruction::I32FromU8
1693            | Instruction::I32FromS8
1694            | Instruction::I32FromU16
1695            | Instruction::I32FromS16
1696            | Instruction::I32FromU32 => {
1697                results.push(format!("(int32_t) ({})", operands[0]));
1698            }
1699            Instruction::I32FromS32 | Instruction::I64FromS64 => results.push(operands[0].clone()),
1700            Instruction::I64FromU64 => {
1701                results.push(format!("(int64_t) ({})", operands[0]));
1702            }
1703
1704            // f32/f64 have the same representation in the import type and in C,
1705            // so no conversions necessary.
1706            Instruction::F32FromFloat32
1707            | Instruction::F64FromFloat64
1708            | Instruction::Float32FromF32
1709            | Instruction::Float64FromF64 => {
1710                results.push(operands[0].clone());
1711            }
1712
1713            // TODO: checked
1714            Instruction::CharFromI32 => {
1715                results.push(format!("(uint32_t) ({})", operands[0]));
1716            }
1717            Instruction::I32FromChar => {
1718                results.push(format!("(int32_t) ({})", operands[0]));
1719            }
1720
1721            Instruction::Bitcasts { casts } => {
1722                for (cast, op) in casts.iter().zip(operands) {
1723                    let op = op;
1724                    match cast {
1725                        Bitcast::I32ToF32 | Bitcast::I64ToF32 => {
1726                            results
1727                                .push(format!("((union {{ int32_t a; float b; }}){{ {} }}).b", op));
1728                        }
1729                        Bitcast::F32ToI32 | Bitcast::F32ToI64 => {
1730                            results
1731                                .push(format!("((union {{ float a; int32_t b; }}){{ {} }}).b", op));
1732                        }
1733                        Bitcast::I64ToF64 => {
1734                            results.push(format!(
1735                                "((union {{ int64_t a; double b; }}){{ {} }}).b",
1736                                op
1737                            ));
1738                        }
1739                        Bitcast::F64ToI64 => {
1740                            results.push(format!(
1741                                "((union {{ double a; int64_t b; }}){{ {} }}).b",
1742                                op
1743                            ));
1744                        }
1745                        Bitcast::I32ToI64 => {
1746                            results.push(format!("(int64_t) {}", op));
1747                        }
1748                        Bitcast::I64ToI32 => {
1749                            results.push(format!("(int32_t) {}", op));
1750                        }
1751                        Bitcast::None => results.push(op.to_string()),
1752                    }
1753                }
1754            }
1755
1756            Instruction::BoolFromI32 | Instruction::I32FromBool => {
1757                results.push(operands[0].clone());
1758            }
1759
1760            Instruction::RecordLower { record, .. } => {
1761                let op = &operands[0];
1762                for f in record.fields.iter() {
1763                    results.push(format!("({}).{}", op, to_c_ident(&f.name)));
1764                }
1765            }
1766            Instruction::RecordLift { ty, .. } => {
1767                let name = self.gen.type_string(&Type::Id(*ty));
1768                let mut result = format!("({}) {{\n", name);
1769                for op in operands {
1770                    uwriteln!(result, "{},", op);
1771                }
1772                result.push_str("}");
1773                results.push(result);
1774            }
1775
1776            Instruction::TupleLower { tuple, .. } => {
1777                let op = &operands[0];
1778                for i in 0..tuple.types.len() {
1779                    results.push(format!("({}).f{}", op, i));
1780                }
1781            }
1782            Instruction::TupleLift { ty, .. } => {
1783                let name = self.gen.type_string(&Type::Id(*ty));
1784                let mut result = format!("({}) {{\n", name);
1785                for op in operands {
1786                    uwriteln!(result, "{},", op);
1787                }
1788                result.push_str("}");
1789                results.push(result);
1790            }
1791
1792            // TODO: checked
1793            Instruction::FlagsLower { flags, ty, .. } => match flags_repr(flags) {
1794                Int::U8 | Int::U16 | Int::U32 => {
1795                    results.push(operands.pop().unwrap());
1796                }
1797                Int::U64 => {
1798                    let name = self.gen.type_string(&Type::Id(*ty));
1799                    let tmp = self.locals.tmp("flags");
1800                    uwriteln!(self.src, "{name} {tmp} = {};", operands[0]);
1801                    results.push(format!("{tmp} & 0xffffffff"));
1802                    results.push(format!("({tmp} >> 32) & 0xffffffff"));
1803                }
1804            },
1805
1806            Instruction::FlagsLift { flags, ty, .. } => match flags_repr(flags) {
1807                Int::U8 | Int::U16 | Int::U32 => {
1808                    results.push(operands.pop().unwrap());
1809                }
1810                Int::U64 => {
1811                    let name = self.gen.type_string(&Type::Id(*ty));
1812                    let op0 = &operands[0];
1813                    let op1 = &operands[1];
1814                    results.push(format!("(({name}) ({op0})) | ((({name}) ({op1})) << 32)"));
1815                }
1816            },
1817
1818            Instruction::VariantPayloadName => {
1819                let name = self.locals.tmp("payload");
1820                results.push(format!("*{}", name));
1821                self.payloads.push(name);
1822            }
1823
1824            Instruction::VariantLower {
1825                variant,
1826                results: result_types,
1827                ..
1828            } => {
1829                let blocks = self
1830                    .blocks
1831                    .drain(self.blocks.len() - variant.cases.len()..)
1832                    .collect::<Vec<_>>();
1833                let payloads = self
1834                    .payloads
1835                    .drain(self.payloads.len() - variant.cases.len()..)
1836                    .collect::<Vec<_>>();
1837
1838                let mut variant_results = Vec::with_capacity(result_types.len());
1839                for ty in result_types.iter() {
1840                    let name = self.locals.tmp("variant");
1841                    results.push(name.clone());
1842                    self.src.push_str(wasm_type(*ty));
1843                    self.src.push_str(" ");
1844                    self.src.push_str(&name);
1845                    self.src.push_str(";\n");
1846                    variant_results.push(name);
1847                }
1848
1849                let expr_to_match = format!("({}).tag", operands[0]);
1850
1851                uwriteln!(self.src, "switch ((int32_t) {}) {{", expr_to_match);
1852                for (i, ((case, (block, block_results)), payload)) in
1853                    variant.cases.iter().zip(blocks).zip(payloads).enumerate()
1854                {
1855                    uwriteln!(self.src, "case {}: {{", i);
1856                    if let Some(ty) = self.gen.get_nonempty_type(case.ty.as_ref()) {
1857                        let ty = self.gen.type_string(ty);
1858                        uwrite!(
1859                            self.src,
1860                            "const {} *{} = &({}).val",
1861                            ty,
1862                            payload,
1863                            operands[0],
1864                        );
1865                        self.src.push_str(".");
1866                        self.src.push_str(&to_c_ident(&case.name));
1867                        self.src.push_str(";\n");
1868                    }
1869                    self.src.push_str(&block);
1870
1871                    for (name, result) in variant_results.iter().zip(&block_results) {
1872                        uwriteln!(self.src, "{} = {};", name, result);
1873                    }
1874                    self.src.push_str("break;\n}\n");
1875                }
1876                self.src.push_str("}\n");
1877            }
1878
1879            Instruction::VariantLift { variant, ty, .. } => {
1880                let blocks = self
1881                    .blocks
1882                    .drain(self.blocks.len() - variant.cases.len()..)
1883                    .collect::<Vec<_>>();
1884
1885                let ty = self.gen.type_string(&Type::Id(*ty));
1886                let result = self.locals.tmp("variant");
1887                uwriteln!(self.src, "{} {};", ty, result);
1888                uwriteln!(self.src, "{}.tag = {};", result, operands[0]);
1889                uwriteln!(self.src, "switch ((int32_t) {}.tag) {{", result);
1890                for (i, (case, (block, block_results))) in
1891                    variant.cases.iter().zip(blocks).enumerate()
1892                {
1893                    uwriteln!(self.src, "case {}: {{", i);
1894                    self.src.push_str(&block);
1895                    assert!(block_results.len() == (case.ty.is_some() as usize));
1896
1897                    if let Some(_) = self.gen.get_nonempty_type(case.ty.as_ref()) {
1898                        let mut dst = format!("{}.val", result);
1899                        dst.push_str(".");
1900                        dst.push_str(&to_c_ident(&case.name));
1901                        self.store_op(&block_results[0], &dst);
1902                    }
1903                    self.src.push_str("break;\n}\n");
1904                }
1905                self.src.push_str("}\n");
1906                results.push(result);
1907            }
1908
1909            Instruction::UnionLower {
1910                union,
1911                results: result_types,
1912                ..
1913            } => {
1914                let blocks = self
1915                    .blocks
1916                    .drain(self.blocks.len() - union.cases.len()..)
1917                    .collect::<Vec<_>>();
1918                let payloads = self
1919                    .payloads
1920                    .drain(self.payloads.len() - union.cases.len()..)
1921                    .collect::<Vec<_>>();
1922
1923                let mut union_results = Vec::with_capacity(result_types.len());
1924                for ty in result_types.iter() {
1925                    let name = self.locals.tmp("unionres");
1926                    results.push(name.clone());
1927                    let ty = wasm_type(*ty);
1928                    uwriteln!(self.src, "{ty} {name};");
1929                    union_results.push(name);
1930                }
1931
1932                let op0 = &operands[0];
1933                uwriteln!(self.src, "switch (({op0}).tag) {{");
1934                for (i, ((case, (block, block_results)), payload)) in
1935                    union.cases.iter().zip(blocks).zip(payloads).enumerate()
1936                {
1937                    uwriteln!(self.src, "case {i}: {{");
1938                    if !self.gen.is_empty_type(&case.ty) {
1939                        let ty = self.gen.type_string(&case.ty);
1940                        uwriteln!(self.src, "const {ty} *{payload} = &({op0}).val.f{i};");
1941                    }
1942                    self.src.push_str(&block);
1943
1944                    for (name, result) in union_results.iter().zip(&block_results) {
1945                        uwriteln!(self.src, "{name} = {result};");
1946                    }
1947                    self.src.push_str("break;\n}\n");
1948                }
1949                self.src.push_str("}\n");
1950            }
1951
1952            Instruction::UnionLift { union, ty, .. } => {
1953                let blocks = self
1954                    .blocks
1955                    .drain(self.blocks.len() - union.cases.len()..)
1956                    .collect::<Vec<_>>();
1957
1958                let ty = self.gen.type_string(&Type::Id(*ty));
1959                let result = self.locals.tmp("unionres");
1960                uwriteln!(self.src, "{} {};", ty, result);
1961                uwriteln!(self.src, "{}.tag = {};", result, operands[0]);
1962                uwriteln!(self.src, "switch ((int32_t) {}.tag) {{", result);
1963                for (i, (_case, (block, block_results))) in
1964                    union.cases.iter().zip(blocks).enumerate()
1965                {
1966                    uwriteln!(self.src, "case {i}: {{");
1967                    self.src.push_str(&block);
1968
1969                    assert!(block_results.len() == 1);
1970                    let dst = format!("{result}.val.f{i}");
1971                    self.store_op(&block_results[0], &dst);
1972                    self.src.push_str("break;\n}\n");
1973                }
1974                self.src.push_str("}\n");
1975                results.push(result);
1976            }
1977
1978            Instruction::OptionLower {
1979                results: result_types,
1980                payload,
1981                ..
1982            } => {
1983                let (mut some, some_results) = self.blocks.pop().unwrap();
1984                let (mut none, none_results) = self.blocks.pop().unwrap();
1985                let some_payload = self.payloads.pop().unwrap();
1986                let _none_payload = self.payloads.pop().unwrap();
1987
1988                for (i, ty) in result_types.iter().enumerate() {
1989                    let name = self.locals.tmp("option");
1990                    results.push(name.clone());
1991                    self.src.push_str(wasm_type(*ty));
1992                    self.src.push_str(" ");
1993                    self.src.push_str(&name);
1994                    self.src.push_str(";\n");
1995                    let some_result = &some_results[i];
1996                    uwriteln!(some, "{name} = {some_result};");
1997                    let none_result = &none_results[i];
1998                    uwriteln!(none, "{name} = {none_result};");
1999                }
2000
2001                let op0 = &operands[0];
2002                let ty = self.gen.type_string(payload);
2003                let bind_some = if self.gen.is_empty_type(payload) {
2004                    String::new()
2005                } else {
2006                    format!("const {ty} *{some_payload} = &({op0}).val;")
2007                };
2008
2009                uwrite!(
2010                    self.src,
2011                    "\
2012                    if (({op0}).is_some) {{
2013                        {bind_some}
2014                        {some}}} else {{
2015                        {none}}}
2016                    "
2017                );
2018            }
2019
2020            Instruction::OptionLift { payload, ty, .. } => {
2021                let (mut some, some_results) = self.blocks.pop().unwrap();
2022                let (mut none, none_results) = self.blocks.pop().unwrap();
2023                assert!(none_results.len() == 0);
2024                assert!(some_results.len() == 1);
2025                let some_result = &some_results[0];
2026
2027                let ty = self.gen.type_string(&Type::Id(*ty));
2028                let result = self.locals.tmp("option");
2029                uwriteln!(self.src, "{ty} {result};");
2030                let op0 = &operands[0];
2031                let set_some = if self.gen.is_empty_type(payload) {
2032                    String::new()
2033                } else {
2034                    format!("{result}.val = {some_result};\n")
2035                };
2036                if none.len() > 0 {
2037                    none.push('\n');
2038                }
2039                if some.len() > 0 {
2040                    some.push('\n');
2041                }
2042                uwrite!(
2043                    self.src,
2044                    "switch ({op0}) {{
2045                        case 0: {{
2046                            {result}.is_some = false;
2047                            {none}\
2048                            break;
2049                        }}
2050                        case 1: {{
2051                            {result}.is_some = true;
2052                            {some}\
2053                            {set_some}\
2054                            break;
2055                        }}
2056                    }}\n"
2057                );
2058                results.push(result);
2059            }
2060
2061            Instruction::ResultLower {
2062                results: result_types,
2063                result,
2064                ..
2065            } => {
2066                let (mut err, err_results) = self.blocks.pop().unwrap();
2067                let (mut ok, ok_results) = self.blocks.pop().unwrap();
2068                let err_payload = self.payloads.pop().unwrap();
2069                let ok_payload = self.payloads.pop().unwrap();
2070
2071                for (i, ty) in result_types.iter().enumerate() {
2072                    let name = self.locals.tmp("result");
2073                    results.push(name.clone());
2074                    self.src.push_str(wasm_type(*ty));
2075                    self.src.push_str(" ");
2076                    self.src.push_str(&name);
2077                    self.src.push_str(";\n");
2078                    let ok_result = &ok_results[i];
2079                    uwriteln!(ok, "{name} = {ok_result};");
2080                    let err_result = &err_results[i];
2081                    uwriteln!(err, "{name} = {err_result};");
2082                }
2083
2084                let op0 = &operands[0];
2085                let bind_ok = if let Some(ok) = self.gen.get_nonempty_type(result.ok.as_ref()) {
2086                    let ok_ty = self.gen.type_string(ok);
2087                    format!("const {ok_ty} *{ok_payload} = &({op0}).val.ok;")
2088                } else {
2089                    String::new()
2090                };
2091                let bind_err = if let Some(err) = self.gen.get_nonempty_type(result.err.as_ref()) {
2092                    let err_ty = self.gen.type_string(err);
2093                    format!("const {err_ty} *{err_payload} = &({op0}).val.err;")
2094                } else {
2095                    String::new()
2096                };
2097                uwrite!(
2098                    self.src,
2099                    "\
2100                    if (({op0}).is_err) {{
2101                        {bind_err}\
2102                        {err}\
2103                    }} else {{
2104                        {bind_ok}\
2105                        {ok}\
2106                    }}
2107                    "
2108                );
2109            }
2110
2111            Instruction::ResultLift { result, ty, .. } => {
2112                let (mut err, err_results) = self.blocks.pop().unwrap();
2113                assert!(err_results.len() == (result.err.is_some() as usize));
2114                let (mut ok, ok_results) = self.blocks.pop().unwrap();
2115                assert!(ok_results.len() == (result.ok.is_some() as usize));
2116
2117                if err.len() > 0 {
2118                    err.push_str("\n");
2119                }
2120                if ok.len() > 0 {
2121                    ok.push_str("\n");
2122                }
2123
2124                let result_tmp = self.locals.tmp("result");
2125                let set_ok = if let Some(_) = self.gen.get_nonempty_type(result.ok.as_ref()) {
2126                    let ok_result = &ok_results[0];
2127                    format!("{result_tmp}.val.ok = {ok_result};\n")
2128                } else {
2129                    String::new()
2130                };
2131                let set_err = if let Some(_) = self.gen.get_nonempty_type(result.err.as_ref()) {
2132                    let err_result = &err_results[0];
2133                    format!("{result_tmp}.val.err = {err_result};\n")
2134                } else {
2135                    String::new()
2136                };
2137
2138                let ty = self.gen.type_string(&Type::Id(*ty));
2139                uwriteln!(self.src, "{ty} {result_tmp};");
2140                let op0 = &operands[0];
2141                uwriteln!(
2142                    self.src,
2143                    "switch ({op0}) {{
2144                        case 0: {{
2145                            {result_tmp}.is_err = false;
2146                            {ok}\
2147                            {set_ok}\
2148                            break;
2149                        }}
2150                        case 1: {{
2151                            {result_tmp}.is_err = true;
2152                            {err}\
2153                            {set_err}\
2154                            break;
2155                        }}
2156                    }}"
2157                );
2158                results.push(result_tmp);
2159            }
2160
2161            Instruction::EnumLower { .. } => results.push(format!("(int32_t) {}", operands[0])),
2162            Instruction::EnumLift { .. } => results.push(operands.pop().unwrap()),
2163
2164            Instruction::ListCanonLower { .. } | Instruction::StringLower { .. } => {
2165                results.push(format!("(int32_t) ({}).ptr", operands[0]));
2166                results.push(format!("(int32_t) ({}).len", operands[0]));
2167            }
2168            Instruction::ListCanonLift { element, ty, .. } => {
2169                let list_name = self.gen.type_string(&Type::Id(*ty));
2170                let elem_name = self.gen.type_string(element);
2171                results.push(format!(
2172                    "({}) {{ ({}*)({}), (size_t)({}) }}",
2173                    list_name, elem_name, operands[0], operands[1]
2174                ));
2175            }
2176            Instruction::StringLift { .. } => {
2177                let list_name = self.gen.type_string(&Type::String);
2178                results.push(format!(
2179                    "({}) {{ ({}*)({}), (size_t)({}) }}",
2180                    list_name,
2181                    self.gen.gen.char_type(),
2182                    operands[0],
2183                    operands[1]
2184                ));
2185            }
2186
2187            Instruction::ListLower { .. } => {
2188                let _body = self.blocks.pop().unwrap();
2189                results.push(format!("(int32_t) ({}).ptr", operands[0]));
2190                results.push(format!("(int32_t) ({}).len", operands[0]));
2191            }
2192
2193            Instruction::ListLift { element, ty, .. } => {
2194                let _body = self.blocks.pop().unwrap();
2195                let list_name = self.gen.type_string(&Type::Id(*ty));
2196                let elem_name = self.gen.type_string(element);
2197                results.push(format!(
2198                    "({}) {{ ({}*)({}), (size_t)({}) }}",
2199                    list_name, elem_name, operands[0], operands[1]
2200                ));
2201            }
2202            Instruction::IterElem { .. } => results.push("e".to_string()),
2203            Instruction::IterBasePointer => results.push("base".to_string()),
2204
2205            Instruction::CallWasm { sig, .. } => {
2206                match sig.results.len() {
2207                    0 => {}
2208                    1 => {
2209                        self.src.push_str(wasm_type(sig.results[0]));
2210                        let ret = self.locals.tmp("ret");
2211                        self.wasm_return = Some(ret.clone());
2212                        uwrite!(self.src, " {} = ", ret);
2213                        results.push(ret);
2214                    }
2215                    _ => unimplemented!(),
2216                }
2217                self.src.push_str(self.func_to_call);
2218                self.src.push_str("(");
2219                for (i, op) in operands.iter().enumerate() {
2220                    if i > 0 {
2221                        self.src.push_str(", ");
2222                    }
2223                    self.src.push_str(op);
2224                }
2225                self.src.push_str(");\n");
2226            }
2227
2228            Instruction::CallInterface { func } => {
2229                let mut args = String::new();
2230                for (i, (op, (byref, _))) in operands.iter().zip(&self.sig.params).enumerate() {
2231                    if i > 0 {
2232                        args.push_str(", ");
2233                    }
2234                    let ty = &func.params[i].1;
2235                    if *byref {
2236                        let name = self.locals.tmp("arg");
2237                        let ty = self.gen.type_string(ty);
2238                        uwriteln!(self.src, "{} {} = {};", ty, name, op);
2239                        args.push_str("&");
2240                        args.push_str(&name);
2241                    } else {
2242                        if !self.gen.in_import {
2243                            if let Type::Id(id) = ty {
2244                                if let TypeDefKind::Option(option_ty) =
2245                                    &self.gen.resolve.types[*id].kind
2246                                {
2247                                    if self.gen.is_empty_type(option_ty) {
2248                                        uwrite!(args, "{op}.is_some ? (void*)1 : NULL");
2249                                    } else {
2250                                        uwrite!(args, "{op}.is_some ? &({op}.val) : NULL");
2251                                    }
2252                                    continue;
2253                                }
2254                            }
2255                        }
2256                        args.push_str(op);
2257                    }
2258                }
2259                match &self.sig.ret.scalar {
2260                    None => {
2261                        let mut retptrs = Vec::new();
2262                        for ty in self.sig.ret.retptrs.iter() {
2263                            let name = self.locals.tmp("ret");
2264                            let ty = self.gen.type_string(ty);
2265                            uwriteln!(self.src, "{} {};", ty, name);
2266                            if args.len() > 0 {
2267                                args.push_str(", ");
2268                            }
2269                            args.push_str("&");
2270                            args.push_str(&name);
2271                            retptrs.push(name);
2272                        }
2273                        uwriteln!(self.src, "{}({});", self.sig.name, args);
2274                        results.extend(retptrs);
2275                    }
2276                    Some(Scalar::Void) => {
2277                        uwriteln!(self.src, "{}({});", self.sig.name, args);
2278                    }
2279                    Some(Scalar::Type(_)) => {
2280                        let ret = self.locals.tmp("ret");
2281                        let ty = self
2282                            .gen
2283                            .type_string(func.results.iter_types().next().unwrap());
2284                        uwriteln!(self.src, "{} {} = {}({});", ty, ret, self.sig.name, args);
2285                        results.push(ret);
2286                    }
2287                    Some(Scalar::OptionBool(ty)) => {
2288                        let ret = self.locals.tmp("ret");
2289                        let val = self.locals.tmp("val");
2290                        if args.len() > 0 {
2291                            args.push_str(", ");
2292                        }
2293                        args.push_str("&");
2294                        args.push_str(&val);
2295                        let payload_ty = self.gen.type_string(ty);
2296                        uwriteln!(self.src, "{} {};", payload_ty, val);
2297                        uwriteln!(self.src, "bool {} = {}({});", ret, self.sig.name, args);
2298                        let option_ty = self
2299                            .gen
2300                            .type_string(func.results.iter_types().next().unwrap());
2301                        let option_ret = self.locals.tmp("ret");
2302                        if !self.gen.is_empty_type(ty) {
2303                            uwrite!(
2304                                self.src,
2305                                "
2306                                    {ty} {ret};
2307                                    {ret}.is_some = {tag};
2308                                    {ret}.val = {val};
2309                                ",
2310                                ty = option_ty,
2311                                ret = option_ret,
2312                                tag = ret,
2313                                val = val,
2314                            );
2315                        } else {
2316                            uwrite!(
2317                                self.src,
2318                                "
2319                                    {ty} {ret};
2320                                    {ret}.is_some = {tag};
2321                                ",
2322                                ty = option_ty,
2323                                ret = option_ret,
2324                                tag = ret,
2325                            );
2326                        }
2327                        results.push(option_ret);
2328                    }
2329                    Some(Scalar::ResultBool(ok, err)) => {
2330                        let result_ty = self
2331                            .gen
2332                            .type_string(func.results.iter_types().next().unwrap());
2333                        let ret = self.locals.tmp("ret");
2334                        let mut ret_iter = self.sig.ret.retptrs.iter();
2335                        uwriteln!(self.src, "{result_ty} {ret};");
2336                        let ok_name = if ok.is_some() {
2337                            if let Some(ty) = ret_iter.next() {
2338                                let val = self.locals.tmp("ok");
2339                                if args.len() > 0 {
2340                                    uwrite!(args, ", ");
2341                                }
2342                                uwrite!(args, "&{val}");
2343                                let ty = self.gen.type_string(ty);
2344                                uwriteln!(self.src, "{} {};", ty, val);
2345                                Some(val)
2346                            } else {
2347                                None
2348                            }
2349                        } else {
2350                            None
2351                        };
2352                        let err_name = if let Some(ty) = ret_iter.next() {
2353                            let val = self.locals.tmp("err");
2354                            if args.len() > 0 {
2355                                uwrite!(args, ", ")
2356                            }
2357                            uwrite!(args, "&{val}");
2358                            let ty = self.gen.type_string(ty);
2359                            uwriteln!(self.src, "{} {};", ty, val);
2360                            Some(val)
2361                        } else {
2362                            None
2363                        };
2364                        assert!(ret_iter.next().is_none());
2365                        uwrite!(self.src, "");
2366                        uwriteln!(self.src, "{ret}.is_err = !{}({args});", self.sig.name);
2367                        if self.gen.get_nonempty_type(err.as_ref()).is_some() {
2368                            if let Some(err_name) = err_name {
2369                                uwriteln!(
2370                                    self.src,
2371                                    "if ({ret}.is_err) {{
2372                                        {ret}.val.err = {err_name};
2373                                    }}",
2374                                );
2375                            }
2376                        }
2377                        if self.gen.get_nonempty_type(ok.as_ref()).is_some() {
2378                            if let Some(ok_name) = ok_name {
2379                                uwriteln!(
2380                                    self.src,
2381                                    "if (!{ret}.is_err) {{
2382                                        {ret}.val.ok = {ok_name};
2383                                    }}"
2384                                );
2385                            } else {
2386                                uwrite!(self.src, "\n");
2387                            }
2388                        }
2389                        results.push(ret);
2390                    }
2391                }
2392            }
2393            Instruction::Return { .. } if self.gen.in_import => match self.sig.ret.scalar {
2394                None => {
2395                    for op in operands.iter() {
2396                        self.store_in_retptr(op);
2397                    }
2398                }
2399                Some(Scalar::Void) => {
2400                    assert!(operands.is_empty());
2401                }
2402                Some(Scalar::Type(_)) => {
2403                    assert_eq!(operands.len(), 1);
2404                    self.src.push_str("return ");
2405                    self.src.push_str(&operands[0]);
2406                    self.src.push_str(";\n");
2407                }
2408                Some(Scalar::OptionBool(o)) => {
2409                    assert_eq!(operands.len(), 1);
2410                    let variant = &operands[0];
2411                    if !self.gen.is_empty_type(&o) {
2412                        self.store_in_retptr(&format!("{}.val", variant));
2413                    }
2414                    self.src.push_str("return ");
2415                    self.src.push_str(&variant);
2416                    self.src.push_str(".is_some;\n");
2417                }
2418                Some(Scalar::ResultBool(ok, err)) => {
2419                    assert_eq!(operands.len(), 1);
2420                    let variant = &operands[0];
2421                    assert!(self.sig.retptrs.len() <= 2);
2422                    uwriteln!(self.src, "if (!{}.is_err) {{", variant);
2423                    if let Some(_) = self.gen.get_nonempty_type(ok.as_ref()) {
2424                        if self.sig.retptrs.len() == 2 {
2425                            self.store_in_retptr(&format!("{}.val.ok", variant));
2426                        } else if self.sig.retptrs.len() == 1 && ok.is_some() {
2427                            self.store_in_retptr(&format!("{}.val.ok", variant));
2428                        }
2429                    }
2430                    uwriteln!(
2431                        self.src,
2432                        "   return 1;
2433                            }} else {{"
2434                    );
2435                    if let Some(_) = self.gen.get_nonempty_type(err.as_ref()) {
2436                        if self.sig.retptrs.len() == 2 {
2437                            self.store_in_retptr(&format!("{}.val.err", variant));
2438                        } else if self.sig.retptrs.len() == 1 && !ok.is_some() {
2439                            self.store_in_retptr(&format!("{}.val.err", variant));
2440                        }
2441                    }
2442                    uwriteln!(
2443                        self.src,
2444                        "   return 0;
2445                            }}"
2446                    );
2447                }
2448            },
2449            Instruction::Return { amt, .. } => {
2450                assert!(*amt <= 1);
2451                if *amt == 1 {
2452                    uwriteln!(self.src, "return {};", operands[0]);
2453                }
2454            }
2455
2456            Instruction::I32Load { offset } => self.load("int32_t", *offset, operands, results),
2457            Instruction::I64Load { offset } => self.load("int64_t", *offset, operands, results),
2458            Instruction::F32Load { offset } => self.load("float", *offset, operands, results),
2459            Instruction::F64Load { offset } => self.load("double", *offset, operands, results),
2460            Instruction::I32Store { offset } => self.store("int32_t", *offset, operands),
2461            Instruction::I64Store { offset } => self.store("int64_t", *offset, operands),
2462            Instruction::F32Store { offset } => self.store("float", *offset, operands),
2463            Instruction::F64Store { offset } => self.store("double", *offset, operands),
2464            Instruction::I32Store8 { offset } => self.store("int8_t", *offset, operands),
2465            Instruction::I32Store16 { offset } => self.store("int16_t", *offset, operands),
2466
2467            Instruction::I32Load8U { offset } => {
2468                self.load_ext("uint8_t", *offset, operands, results)
2469            }
2470            Instruction::I32Load8S { offset } => {
2471                self.load_ext("int8_t", *offset, operands, results)
2472            }
2473            Instruction::I32Load16U { offset } => {
2474                self.load_ext("uint16_t", *offset, operands, results)
2475            }
2476            Instruction::I32Load16S { offset } => {
2477                self.load_ext("int16_t", *offset, operands, results)
2478            }
2479
2480            Instruction::GuestDeallocate { .. } => {
2481                uwriteln!(self.src, "free((void*) ({}));", operands[0]);
2482            }
2483            Instruction::GuestDeallocateString => {
2484                uwriteln!(self.src, "if (({}) > 0) {{", operands[1]);
2485                uwriteln!(self.src, "free((void*) ({}));", operands[0]);
2486                uwriteln!(self.src, "}}");
2487            }
2488            Instruction::GuestDeallocateVariant { blocks } => {
2489                let blocks = self
2490                    .blocks
2491                    .drain(self.blocks.len() - blocks..)
2492                    .collect::<Vec<_>>();
2493
2494                uwriteln!(self.src, "switch ((int32_t) {}) {{", operands[0]);
2495                for (i, (block, results)) in blocks.into_iter().enumerate() {
2496                    assert!(results.is_empty());
2497                    uwriteln!(self.src, "case {}: {{", i);
2498                    self.src.push_str(&block);
2499                    self.src.push_str("break;\n}\n");
2500                }
2501                self.src.push_str("}\n");
2502            }
2503            Instruction::GuestDeallocateList { element } => {
2504                let (body, results) = self.blocks.pop().unwrap();
2505                assert!(results.is_empty());
2506                let ptr = self.locals.tmp("ptr");
2507                let len = self.locals.tmp("len");
2508                uwriteln!(self.src, "int32_t {ptr} = {};", operands[0]);
2509                uwriteln!(self.src, "int32_t {len} = {};", operands[1]);
2510                let i = self.locals.tmp("i");
2511                uwriteln!(self.src, "for (int32_t {i} = 0; {i} < {len}; {i}++) {{");
2512                let size = self.gen.gen.sizes.size(element);
2513                uwriteln!(self.src, "int32_t base = {ptr} + {i} * {size};");
2514                uwriteln!(self.src, "(void) base;");
2515                uwrite!(self.src, "{body}");
2516                uwriteln!(self.src, "}}");
2517                uwriteln!(self.src, "if ({len} > 0) {{");
2518                uwriteln!(self.src, "free((void*) ({ptr}));");
2519                uwriteln!(self.src, "}}");
2520            }
2521
2522            i => unimplemented!("{:?}", i),
2523        }
2524    }
2525}
2526
2527#[derive(Default, Clone, Copy)]
2528enum SourceType {
2529    #[default]
2530    HDefs,
2531    HFns,
2532    HHelpers,
2533    // CDefs,
2534    // CFns,
2535    // CHelpers,
2536    // CAdapters,
2537}
2538
2539#[derive(Default)]
2540struct Source {
2541    h_defs: wit_bindgen_core::Source,
2542    h_fns: wit_bindgen_core::Source,
2543    h_helpers: wit_bindgen_core::Source,
2544    c_defs: wit_bindgen_core::Source,
2545    c_fns: wit_bindgen_core::Source,
2546    c_helpers: wit_bindgen_core::Source,
2547    c_adapters: wit_bindgen_core::Source,
2548}
2549
2550impl Source {
2551    fn print(&mut self, stype: SourceType, s: &str) {
2552        match stype {
2553            SourceType::HDefs => self.h_defs(s),
2554            SourceType::HFns => self.h_fns(s),
2555            SourceType::HHelpers => self.h_helpers(s),
2556            // SourceType::CDefs => self.c_defs(s),
2557            // SourceType::CFns => self.c_fns(s),
2558            // SourceType::CHelpers => self.c_helpers(s),
2559            // SourceType::CAdapters => self.c_adapters(s),
2560        }
2561    }
2562    fn append(&mut self, append_src: &Source) {
2563        self.h_defs.push_str(&append_src.h_defs);
2564        self.h_fns.push_str(&append_src.h_fns);
2565        self.h_helpers.push_str(&append_src.h_helpers);
2566        self.c_defs.push_str(&append_src.c_defs);
2567        self.c_fns.push_str(&append_src.c_fns);
2568        self.c_helpers.push_str(&append_src.c_helpers);
2569        self.c_adapters.push_str(&append_src.c_adapters);
2570    }
2571    fn h_defs(&mut self, s: &str) {
2572        self.h_defs.push_str(s);
2573    }
2574    fn h_fns(&mut self, s: &str) {
2575        self.h_fns.push_str(s);
2576    }
2577    fn h_helpers(&mut self, s: &str) {
2578        self.h_helpers.push_str(s);
2579    }
2580    fn c_defs(&mut self, s: &str) {
2581        self.c_defs.push_str(s);
2582    }
2583    fn c_fns(&mut self, s: &str) {
2584        self.c_fns.push_str(s);
2585    }
2586    fn c_helpers(&mut self, s: &str) {
2587        self.c_helpers.push_str(s);
2588    }
2589    fn c_adapters(&mut self, s: &str) {
2590        self.c_adapters.push_str(s);
2591    }
2592}
2593
2594fn wasm_type(ty: WasmType) -> &'static str {
2595    match ty {
2596        WasmType::I32 => "int32_t",
2597        WasmType::I64 => "int64_t",
2598        WasmType::F32 => "float",
2599        WasmType::F64 => "double",
2600    }
2601}
2602
2603fn int_repr(ty: Int) -> &'static str {
2604    match ty {
2605        Int::U8 => "uint8_t",
2606        Int::U16 => "uint16_t",
2607        Int::U32 => "uint32_t",
2608        Int::U64 => "uint64_t",
2609    }
2610}
2611
2612fn flags_repr(f: &Flags) -> Int {
2613    match f.repr() {
2614        FlagsRepr::U8 => Int::U8,
2615        FlagsRepr::U16 => Int::U16,
2616        FlagsRepr::U32(1) => Int::U32,
2617        FlagsRepr::U32(2) => Int::U64,
2618        repr => panic!("unimplemented flags {:?}", repr),
2619    }
2620}
2621
2622pub fn to_c_ident(name: &str) -> String {
2623    match name {
2624        // Escape C keywords.
2625        // Source: https://en.cppreference.com/w/c/keyword
2626        "auto" => "auto_".into(),
2627        "else" => "else_".into(),
2628        "long" => "long_".into(),
2629        "switch" => "switch_".into(),
2630        "break" => "break_".into(),
2631        "enum" => "enum_".into(),
2632        "register" => "register_".into(),
2633        "typedef" => "typedef_".into(),
2634        "case" => "case_".into(),
2635        "extern" => "extern_".into(),
2636        "return" => "return_".into(),
2637        "union" => "union_".into(),
2638        "char" => "char_".into(),
2639        "float" => "float_".into(),
2640        "short" => "short_".into(),
2641        "unsigned" => "unsigned_".into(),
2642        "const" => "const_".into(),
2643        "for" => "for_".into(),
2644        "signed" => "signed_".into(),
2645        "void" => "void_".into(),
2646        "continue" => "continue_".into(),
2647        "goto" => "goto_".into(),
2648        "sizeof" => "sizeof_".into(),
2649        "volatile" => "volatile_".into(),
2650        "default" => "default_".into(),
2651        "if" => "if_".into(),
2652        "static" => "static_".into(),
2653        "while" => "while_".into(),
2654        "do" => "do_".into(),
2655        "int" => "int_".into(),
2656        "struct" => "struct_".into(),
2657        "_Packed" => "_Packed_".into(),
2658        "double" => "double_".into(),
2659        s => s.to_snake_case(),
2660    }
2661}