wit_bindgen_c/
lib.rs

1pub mod component_type_object;
2
3use anyhow::Result;
4use heck::*;
5use indexmap::IndexSet;
6use std::collections::{HashMap, HashSet};
7use std::fmt::Write;
8use std::mem;
9use wit_bindgen_core::abi::{
10    self, AbiVariant, Bindgen, Bitcast, Instruction, LiftLower, WasmSignature, WasmType,
11};
12use wit_bindgen_core::{
13    AnonymousTypeGenerator, AsyncFilterSet, Direction, Files, InterfaceGenerator as _, Ns,
14    WorldGenerator, dealias, uwrite, uwriteln, wit_parser::*,
15};
16use wit_component::StringEncoding;
17
18#[derive(Default)]
19struct C {
20    src: Source,
21    opts: Opts,
22    h_includes: Vec<String>,
23    c_includes: Vec<String>,
24    return_pointer_area_size: ArchitectureSize,
25    return_pointer_area_align: Alignment,
26    names: Ns,
27    needs_string: bool,
28    needs_union_int32_float: bool,
29    needs_union_float_int32: bool,
30    needs_union_int64_double: bool,
31    needs_union_double_int64: bool,
32    needs_async: bool,
33    prim_names: HashSet<String>,
34    world: String,
35    sizes: SizeAlign,
36    renamed_interfaces: HashMap<WorldKey, String>,
37
38    world_id: Option<WorldId>,
39    dtor_funcs: HashMap<TypeId, String>,
40    type_names: HashMap<TypeId, String>,
41    resources: HashMap<TypeId, ResourceInfo>,
42    futures: IndexSet<TypeId>,
43}
44
45#[derive(Default)]
46pub struct ResourceInfo {
47    pub direction: Direction,
48    own: String,
49    borrow: String,
50    drop_fn: String,
51}
52
53#[derive(Default, Debug, Eq, PartialEq, Clone, Copy)]
54#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
55pub enum Enabled {
56    #[default]
57    No,
58    Yes,
59}
60
61impl std::fmt::Display for Enabled {
62    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63        match self {
64            Self::Yes => write!(f, "yes"),
65            Self::No => write!(f, "no"),
66        }
67    }
68}
69
70#[derive(Default, Debug, Clone)]
71#[cfg_attr(feature = "clap", derive(clap::Parser))]
72pub struct Opts {
73    /// Skip emitting component allocation helper functions
74    #[cfg_attr(feature = "clap", arg(long))]
75    pub no_helpers: bool,
76
77    /// Set component string encoding
78    #[cfg_attr(
79        feature = "clap",
80        arg(
81            long,
82            default_value_t = StringEncoding::default(),
83            value_name = "ENCODING",
84        ),
85    )]
86    pub string_encoding: StringEncoding,
87
88    /// Skip optional null pointer and boolean result argument signature
89    /// flattening
90    #[cfg_attr(feature = "clap", arg(long, default_value_t = false))]
91    pub no_sig_flattening: bool,
92
93    /// Skip generating an object file which contains type information for the
94    /// world that is being generated.
95    #[cfg_attr(feature = "clap", arg(long, default_value_t = false))]
96    pub no_object_file: bool,
97
98    /// Rename the interface `K` to `V` in the generated source code.
99    #[cfg_attr(feature = "clap", arg(long, name = "K=V", value_parser = parse_rename))]
100    pub rename: Vec<(String, String)>,
101
102    /// Rename the world in the generated source code and file names.
103    #[cfg_attr(feature = "clap", arg(long, value_name = "NAME"))]
104    pub rename_world: Option<String>,
105
106    /// Add the specified suffix to the name of the custome section containing
107    /// the component type.
108    #[cfg_attr(feature = "clap", arg(long, value_name = "STRING"))]
109    pub type_section_suffix: Option<String>,
110
111    /// Configure the autodropping of borrows in exported functions.
112    #[cfg_attr(
113        feature = "clap",
114        arg(
115            long,
116            default_value_t = Enabled::default(),
117            value_name = "ENABLED",
118        ),
119    )]
120    pub autodrop_borrows: Enabled,
121
122    #[cfg_attr(feature = "clap", clap(flatten))]
123    pub async_: AsyncFilterSet,
124}
125
126#[cfg(feature = "clap")]
127fn parse_rename(name: &str) -> Result<(String, String)> {
128    let mut parts = name.splitn(2, '=');
129    let to_rename = parts.next().unwrap();
130    match parts.next() {
131        Some(part) => Ok((to_rename.to_string(), part.to_string())),
132        None => anyhow::bail!("`--rename` option must have an `=` in it (e.g. `--rename a=b`)"),
133    }
134}
135
136impl Opts {
137    pub fn build(&self) -> Box<dyn WorldGenerator> {
138        let mut r = C::default();
139        r.opts = self.clone();
140        Box::new(r)
141    }
142}
143
144#[derive(Clone, Debug, Default)]
145struct Return {
146    scalar: Option<Scalar>,
147    retptrs: Vec<Type>,
148}
149
150#[derive(Clone)]
151struct CSig {
152    name: String,
153    sig: String,
154    params: Vec<(bool, String)>,
155    ret: Return,
156    retptrs: Vec<String>,
157}
158
159#[derive(Clone, Debug)]
160enum Scalar {
161    Void,
162    OptionBool(Type),
163    ResultBool(Option<Type>, Option<Type>),
164    Type(Type),
165}
166
167impl WorldGenerator for C {
168    fn preprocess(&mut self, resolve: &Resolve, world: WorldId) {
169        self.world = self
170            .opts
171            .rename_world
172            .clone()
173            .unwrap_or_else(|| resolve.worlds[world].name.clone());
174        self.sizes.fill(resolve);
175        self.world_id = Some(world);
176
177        let mut interfaces = HashMap::new();
178        let world = &resolve.worlds[world];
179        for (key, _item) in world.imports.iter().chain(world.exports.iter()) {
180            let name = resolve.name_world_key(key);
181            interfaces.insert(name, key.clone());
182        }
183
184        for (from, to) in self.opts.rename.iter() {
185            match interfaces.get(from) {
186                Some(key) => {
187                    self.renamed_interfaces.insert(key.clone(), to.clone());
188                }
189                None => {
190                    eprintln!("warning: rename of `{from}` did not match any interfaces");
191                }
192            }
193        }
194    }
195
196    fn import_interface(
197        &mut self,
198        resolve: &Resolve,
199        name: &WorldKey,
200        id: InterfaceId,
201        _files: &mut Files,
202    ) -> Result<()> {
203        let wasm_import_module = resolve.name_world_key(name);
204        let mut r#gen = self.interface(resolve, true, Some(&wasm_import_module));
205        r#gen.interface = Some((id, name));
206        r#gen.define_interface_types(id);
207
208        for (i, (_name, func)) in resolve.interfaces[id].functions.iter().enumerate() {
209            if i == 0 {
210                let name = resolve.name_world_key(name);
211                uwriteln!(r#gen.src.h_fns, "\n// Imported Functions from `{name}`");
212                uwriteln!(r#gen.src.c_fns, "\n// Imported Functions from `{name}`");
213            }
214            r#gen.import(Some(name), func);
215        }
216
217        r#gen.r#gen.src.append(&r#gen.src);
218
219        Ok(())
220    }
221
222    fn import_funcs(
223        &mut self,
224        resolve: &Resolve,
225        world: WorldId,
226        funcs: &[(&str, &Function)],
227        _files: &mut Files,
228    ) {
229        let name = &resolve.worlds[world].name;
230        let mut r#gen = self.interface(resolve, true, Some("$root"));
231        r#gen.define_function_types(funcs);
232
233        for (i, (_name, func)) in funcs.iter().enumerate() {
234            if i == 0 {
235                uwriteln!(r#gen.src.h_fns, "\n// Imported Functions from `{name}`");
236                uwriteln!(r#gen.src.c_fns, "\n// Imported Functions from `{name}`");
237            }
238            r#gen.import(None, func);
239        }
240
241        r#gen.r#gen.src.append(&r#gen.src);
242    }
243
244    fn export_interface(
245        &mut self,
246        resolve: &Resolve,
247        name: &WorldKey,
248        id: InterfaceId,
249        _files: &mut Files,
250    ) -> Result<()> {
251        let mut r#gen = self.interface(resolve, false, None);
252        r#gen.interface = Some((id, name));
253        r#gen.define_interface_types(id);
254
255        for (i, (_name, func)) in resolve.interfaces[id].functions.iter().enumerate() {
256            if i == 0 {
257                let name = resolve.name_world_key(name);
258                uwriteln!(r#gen.src.h_fns, "\n// Exported Functions from `{name}`");
259                uwriteln!(r#gen.src.c_fns, "\n// Exported Functions from `{name}`");
260            }
261            r#gen.export(func, Some(name));
262        }
263
264        r#gen.r#gen.src.append(&r#gen.src);
265        Ok(())
266    }
267
268    fn export_funcs(
269        &mut self,
270        resolve: &Resolve,
271        world: WorldId,
272        funcs: &[(&str, &Function)],
273        _files: &mut Files,
274    ) -> Result<()> {
275        let name = &resolve.worlds[world].name;
276        let mut r#gen = self.interface(resolve, false, None);
277        r#gen.define_function_types(funcs);
278
279        for (i, (_name, func)) in funcs.iter().enumerate() {
280            if i == 0 {
281                uwriteln!(r#gen.src.h_fns, "\n// Exported Functions from `{name}`");
282                uwriteln!(r#gen.src.c_fns, "\n// Exported Functions from `{name}`");
283            }
284            r#gen.export(func, None);
285        }
286
287        r#gen.r#gen.src.append(&r#gen.src);
288        Ok(())
289    }
290
291    fn import_types(
292        &mut self,
293        resolve: &Resolve,
294        _world: WorldId,
295        types: &[(&str, TypeId)],
296        _files: &mut Files,
297    ) {
298        let mut r#gen = self.interface(resolve, true, Some("$root"));
299        let mut live = LiveTypes::default();
300        for (_, id) in types {
301            live.add_type_id(resolve, *id);
302        }
303        r#gen.define_live_types(live);
304        r#gen.r#gen.src.append(&r#gen.src);
305    }
306
307    fn finish(&mut self, resolve: &Resolve, id: WorldId, files: &mut Files) -> Result<()> {
308        let linking_symbol = component_type_object::linking_symbol(&self.world);
309        self.c_include("<stdlib.h>");
310        let snake = self.world.to_snake_case();
311        uwriteln!(
312            self.src.c_adapters,
313            "\n// Ensure that the *_component_type.o object is linked in"
314        );
315        uwrite!(
316            self.src.c_adapters,
317            "
318               extern void {linking_symbol}(void);
319               __attribute__((used))
320               void {linking_symbol}_public_use_in_this_compilation_unit(void) {{
321                   {linking_symbol}();
322               }}
323           ",
324        );
325
326        self.print_intrinsics();
327
328        if self.needs_string {
329            self.c_include("<string.h>");
330            let (strlen, size) = match self.opts.string_encoding {
331                StringEncoding::UTF8 => (format!("strlen(s)"), 1),
332                StringEncoding::UTF16 => {
333                    self.h_include("<uchar.h>");
334                    uwrite!(
335                        self.src.h_helpers,
336                        "
337                            // Returns the length of the UTF-16 string `s` in code units
338                            size_t {snake}_string_len(const char16_t* s);
339                        ",
340                    );
341                    uwrite!(
342                        self.src.c_helpers,
343                        "
344                            size_t {snake}_string_len(const char16_t* s) {{
345                                char16_t* c = (char16_t*)s;
346                                for (; *c; ++c);
347                                return c-s;
348                            }}
349                        ",
350                    );
351                    (format!("{snake}_string_len(s)"), 2)
352                }
353                StringEncoding::CompactUTF16 => unimplemented!(),
354            };
355            let ty = self.char_type();
356            let c_string_ty = match self.opts.string_encoding {
357                StringEncoding::UTF8 => "char",
358                StringEncoding::UTF16 => "char16_t",
359                StringEncoding::CompactUTF16 => panic!("Compact UTF16 unsupported"),
360            };
361            uwrite!(
362                self.src.h_helpers,
363                "
364                   // Sets the string `ret` to reference the input string `s` without copying it
365                   void {snake}_string_set({snake}_string_t *ret, const {c_string_ty} *s);
366
367                   // Creates a copy of the input nul-terminated string `s` and
368                   // stores it into the component model string `ret`.
369                   void {snake}_string_dup({snake}_string_t *ret, const {c_string_ty} *s);
370
371                   // Creates a copy of the input string `s` with length `len` and
372                   // stores it into the component model string `ret`.
373                   // The length is specified in code units (bytes for UTF-8, 16-bit values for UTF-16).
374                   void {snake}_string_dup_n({snake}_string_t *ret, const {c_string_ty} *s, size_t len);
375
376                   // Deallocates the string pointed to by `ret`, deallocating
377                   // the memory behind the string.
378                   void {snake}_string_free({snake}_string_t *ret);\
379               ",
380            );
381            uwrite!(
382                self.src.c_helpers,
383                "
384                   void {snake}_string_set({snake}_string_t *ret, const {c_string_ty} *s) {{
385                       ret->ptr = ({ty}*) s;
386                       ret->len = {strlen};
387                   }}
388
389                   void {snake}_string_dup({snake}_string_t *ret, const {c_string_ty} *s) {{
390                       ret->len = {strlen};
391                       ret->ptr = ({ty}*) cabi_realloc(NULL, 0, {size}, ret->len * {size});
392                       memcpy(ret->ptr, s, ret->len * {size});
393                   }}
394
395                   void {snake}_string_dup_n({snake}_string_t *ret, const {c_string_ty} *s, size_t len) {{
396                       ret->len = len;
397                       ret->ptr = ({ty}*) cabi_realloc(NULL, 0, {size}, ret->len * {size});
398                       memcpy(ret->ptr, s, ret->len * {size});
399                   }}
400
401                   void {snake}_string_free({snake}_string_t *ret) {{
402                       if (ret->len > 0) {{
403                           free(ret->ptr);
404                       }}
405                       ret->ptr = NULL;
406                       ret->len = 0;
407                   }}
408               ",
409            );
410        }
411        if self.needs_union_int32_float {
412            uwriteln!(
413                self.src.c_defs,
414                "\nunion int32_float {{ int32_t a; float b; }};"
415            );
416        }
417        if self.needs_union_float_int32 {
418            uwriteln!(
419                self.src.c_defs,
420                "\nunion float_int32 {{ float a; int32_t b; }};"
421            );
422        }
423        if self.needs_union_int64_double {
424            uwriteln!(
425                self.src.c_defs,
426                "\nunion int64_double {{ int64_t a; double b; }};"
427            );
428        }
429        if self.needs_union_double_int64 {
430            uwriteln!(
431                self.src.c_defs,
432                "\nunion double_int64 {{ double a; int64_t b; }};"
433            );
434        }
435        if self.needs_async || self.futures.len() > 0 {
436            self.generate_async_helpers();
437        }
438        let version = env!("CARGO_PKG_VERSION");
439        let mut h_str = wit_bindgen_core::Source::default();
440
441        wit_bindgen_core::generated_preamble(&mut h_str, version);
442
443        uwrite!(
444            h_str,
445            "#ifndef __BINDINGS_{0}_H
446            #define __BINDINGS_{0}_H
447            #ifdef __cplusplus
448            extern \"C\" {{",
449            self.world.to_shouty_snake_case(),
450        );
451
452        // Deindent the extern C { declaration
453        h_str.deindent(1);
454        uwriteln!(h_str, "\n#endif\n");
455
456        uwriteln!(h_str, "#include <stdint.h>");
457        uwriteln!(h_str, "#include <stdbool.h>");
458        uwriteln!(h_str, "#include <stddef.h>");
459        for include in self.h_includes.iter() {
460            uwriteln!(h_str, "#include {include}");
461        }
462
463        let mut c_str = wit_bindgen_core::Source::default();
464        wit_bindgen_core::generated_preamble(&mut c_str, version);
465        uwriteln!(c_str, "#include \"{snake}.h\"");
466        for include in self.c_includes.iter() {
467            uwriteln!(c_str, "#include {include}");
468        }
469        c_str.push_str(&self.src.c_defs);
470        c_str.push_str(&self.src.c_fns);
471
472        // Declare a statically-allocated return area, if needed. We only do
473        // this for export bindings, because import bindings allocate their
474        // return-area on the stack.
475        if !self.return_pointer_area_size.is_empty() {
476            // Automatic indentation avoided due to `extern "C" {` declaration
477            uwrite!(
478                c_str,
479                "
480                __attribute__((__aligned__({})))
481                static uint8_t RET_AREA[{}];
482                ",
483                self.return_pointer_area_align
484                    .format(POINTER_SIZE_EXPRESSION),
485                self.return_pointer_area_size
486                    .format(POINTER_SIZE_EXPRESSION),
487            );
488        }
489
490        if self.needs_string {
491            uwriteln!(
492                h_str,
493                "
494                typedef struct {snake}_string_t {{\n\
495                  {ty} *ptr;\n\
496                  size_t len;\n\
497                }} {snake}_string_t;",
498                ty = self.char_type(),
499            );
500        }
501
502        if self.src.h_async.len() > 0 {
503            uwriteln!(h_str, "\n// Async Helper Functions");
504            h_str.push_str(&self.src.h_async);
505            h_str.push_str("\n");
506        }
507
508        if self.src.h_defs.len() > 0 {
509            h_str.push_str(&self.src.h_defs);
510        }
511
512        h_str.push_str(&self.src.h_fns);
513
514        if !self.opts.no_helpers && self.src.h_helpers.len() > 0 {
515            uwriteln!(h_str, "\n// Helper Functions");
516            h_str.push_str(&self.src.h_helpers);
517            h_str.push_str("\n");
518        }
519
520        if !self.opts.no_helpers && self.src.c_helpers.len() > 0 {
521            uwriteln!(c_str, "\n// Helper Functions");
522            c_str.push_str(self.src.c_helpers.as_mut_string());
523        }
524
525        if self.src.c_async.len() > 0 {
526            uwriteln!(c_str, "\n// Async Helper Functions");
527            c_str.push_str(&self.src.c_async);
528            c_str.push_str("\n");
529        }
530
531        uwriteln!(c_str, "\n// Component Adapters");
532
533        c_str.push_str(&self.src.c_adapters);
534
535        uwriteln!(
536            h_str,
537            "
538            #ifdef __cplusplus
539            }}
540            #endif
541            #endif"
542        );
543
544        files.push(&format!("{snake}.h"), h_str.as_bytes());
545        files.push(&format!("{snake}.c"), c_str.as_bytes());
546        if !self.opts.no_object_file {
547            files.push(
548                &format!("{snake}_component_type.o",),
549                component_type_object::object(
550                    resolve,
551                    id,
552                    &self.world,
553                    self.opts.string_encoding,
554                    self.opts.type_section_suffix.as_deref(),
555                )
556                .unwrap()
557                .as_slice(),
558            );
559        }
560
561        Ok(())
562    }
563
564    fn pre_export_interface(&mut self, resolve: &Resolve, _files: &mut Files) -> Result<()> {
565        self.remove_types_redefined_by_exports(resolve, self.world_id.unwrap());
566        Ok(())
567    }
568}
569
570impl C {
571    fn interface<'a>(
572        &'a mut self,
573        resolve: &'a Resolve,
574        in_import: bool,
575        wasm_import_module: Option<&'a str>,
576    ) -> InterfaceGenerator<'a> {
577        InterfaceGenerator {
578            src: Source::default(),
579            r#gen: self,
580            resolve,
581            interface: None,
582            in_import,
583            wasm_import_module,
584        }
585    }
586
587    fn h_include(&mut self, s: &str) {
588        self.h_includes.push(s.to_string());
589    }
590
591    fn c_include(&mut self, s: &str) {
592        self.c_includes.push(s.to_string());
593    }
594
595    fn char_type(&self) -> &'static str {
596        match self.opts.string_encoding {
597            StringEncoding::UTF8 => "uint8_t",
598            StringEncoding::UTF16 => "uint16_t",
599            StringEncoding::CompactUTF16 => panic!("Compact UTF16 unsupported"),
600        }
601    }
602
603    fn type_name(&mut self, ty: &Type) -> String {
604        let mut name = String::new();
605        self.push_type_name(ty, &mut name);
606        name
607    }
608
609    fn push_type_name(&mut self, ty: &Type, dst: &mut String) {
610        match ty {
611            Type::Bool => dst.push_str("bool"),
612            Type::Char => dst.push_str("uint32_t"), // TODO: better type?
613            Type::U8 => dst.push_str("uint8_t"),
614            Type::S8 => dst.push_str("int8_t"),
615            Type::U16 => dst.push_str("uint16_t"),
616            Type::S16 => dst.push_str("int16_t"),
617            Type::U32 => dst.push_str("uint32_t"),
618            Type::S32 => dst.push_str("int32_t"),
619            Type::U64 => dst.push_str("uint64_t"),
620            Type::S64 => dst.push_str("int64_t"),
621            Type::F32 => dst.push_str("float"),
622            Type::F64 => dst.push_str("double"),
623            Type::String => {
624                dst.push_str(&self.world.to_snake_case());
625                dst.push_str("_");
626                dst.push_str("string_t");
627                self.needs_string = true;
628            }
629            Type::ErrorContext => dst.push_str("error_context"),
630            Type::Id(id) => {
631                if let Some(name) = self.type_names.get(id) {
632                    dst.push_str(name);
633                    return;
634                }
635
636                panic!("failed to find type name for {id:?}");
637            }
638        }
639    }
640
641    /// Removes all types from `self.{dtor_funcs,type_names,resources}` which
642    /// are redefined in exports.
643    ///
644    /// WIT interfaces can be both imported and exported but they're represented
645    /// with the same `TypeId` internally within the `wit-parser`
646    /// representation. This means that duplicate types need to be generated for
647    /// exports, even if the same interface was already imported. If nothing
648    /// were done here though then the same type imported and exported wouldn't
649    /// generate anything new since preexisting types are skipped in
650    /// `define_live_types`.
651    ///
652    /// This function will trim the sets on `self` to only retain those types
653    /// which exports refer to that come from imports.
654    fn remove_types_redefined_by_exports(&mut self, resolve: &Resolve, world: WorldId) {
655        let live_import_types = imported_types_used_by_exported_interfaces(resolve, world);
656        self.dtor_funcs.retain(|k, _| live_import_types.contains(k));
657        self.type_names.retain(|k, _| live_import_types.contains(k));
658        self.resources.retain(|k, _| live_import_types.contains(k));
659    }
660
661    fn perform_cast(&mut self, op: &str, cast: &Bitcast) -> String {
662        match cast {
663            Bitcast::I32ToF32 | Bitcast::I64ToF32 => {
664                self.needs_union_int32_float = true;
665                format!("((union int32_float){{ (int32_t) {} }}).b", op)
666            }
667            Bitcast::F32ToI32 | Bitcast::F32ToI64 => {
668                self.needs_union_float_int32 = true;
669                format!("((union float_int32){{ {} }}).b", op)
670            }
671            Bitcast::I64ToF64 => {
672                self.needs_union_int64_double = true;
673                format!("((union int64_double){{ (int64_t) {} }}).b", op)
674            }
675            Bitcast::F64ToI64 => {
676                self.needs_union_double_int64 = true;
677                format!("((union double_int64){{ {} }}).b", op)
678            }
679            Bitcast::I32ToI64 | Bitcast::LToI64 | Bitcast::PToP64 => {
680                format!("(int64_t) {}", op)
681            }
682            Bitcast::I64ToI32 | Bitcast::I64ToL => {
683                format!("(int32_t) {}", op)
684            }
685            // P64 is currently represented as int64_t, so no conversion is needed.
686            Bitcast::I64ToP64 | Bitcast::P64ToI64 => {
687                format!("{}", op)
688            }
689            Bitcast::P64ToP | Bitcast::I32ToP | Bitcast::LToP => {
690                format!("(uint8_t *) {}", op)
691            }
692
693            // Cast to uintptr_t to avoid implicit pointer-to-int conversions.
694            Bitcast::PToI32 | Bitcast::PToL => format!("(uintptr_t) {}", op),
695
696            Bitcast::I32ToL | Bitcast::LToI32 | Bitcast::None => op.to_string(),
697
698            Bitcast::Sequence(sequence) => {
699                let [first, second] = &**sequence;
700                let inner = self.perform_cast(op, first);
701                self.perform_cast(&inner, second)
702            }
703        }
704    }
705
706    fn generate_async_helpers(&mut self) {
707        let snake = self.world.to_snake_case();
708        let shouty = self.world.to_shouty_snake_case();
709        uwriteln!(
710            self.src.h_async,
711            "
712typedef uint32_t {snake}_subtask_status_t;
713typedef uint32_t {snake}_subtask_t;
714#define {shouty}_SUBTASK_STATE(status) (({snake}_subtask_state_t) ((status) & 0xf))
715#define {shouty}_SUBTASK_HANDLE(status) (({snake}_subtask_t) ((status) >> 4))
716
717typedef enum {snake}_subtask_state {{
718    {shouty}_SUBTASK_STARTING,
719    {shouty}_SUBTASK_STARTED,
720    {shouty}_SUBTASK_RETURNED,
721    {shouty}_SUBTASK_STARTED_CANCELLED,
722    {shouty}_SUBTASK_RETURNED_CANCELLED,
723}} {snake}_subtask_state_t;
724
725{snake}_subtask_status_t {snake}_subtask_cancel({snake}_subtask_t subtask);
726void {snake}_subtask_drop({snake}_subtask_t subtask);
727
728typedef uint32_t {snake}_callback_code_t;
729#define {shouty}_CALLBACK_CODE_EXIT 0
730#define {shouty}_CALLBACK_CODE_YIELD 1
731#define {shouty}_CALLBACK_CODE_WAIT(set) (2 | (set << 4))
732
733typedef enum {snake}_event_code {{
734    {shouty}_EVENT_NONE,
735    {shouty}_EVENT_SUBTASK,
736    {shouty}_EVENT_STREAM_READ,
737    {shouty}_EVENT_STREAM_WRITE,
738    {shouty}_EVENT_FUTURE_READ,
739    {shouty}_EVENT_FUTURE_WRITE,
740    {shouty}_EVENT_CANCEL,
741}} {snake}_event_code_t;
742
743typedef struct {snake}_event {{
744    {snake}_event_code_t event;
745    uint32_t waitable;
746    uint32_t code;
747}} {snake}_event_t;
748
749typedef uint32_t {snake}_waitable_set_t;
750{snake}_waitable_set_t {snake}_waitable_set_new(void);
751void {snake}_waitable_join(uint32_t waitable, {snake}_waitable_set_t set);
752void {snake}_waitable_set_drop({snake}_waitable_set_t set);
753void {snake}_waitable_set_wait({snake}_waitable_set_t set, {snake}_event_t *event);
754void {snake}_waitable_set_poll({snake}_waitable_set_t set, {snake}_event_t *event);
755
756void {snake}_task_cancel(void);
757
758typedef uint32_t {snake}_waitable_status_t;
759#define {shouty}_WAITABLE_STATE(status) (({snake}_waitable_state_t) ((status) & 0xf))
760#define {shouty}_WAITABLE_COUNT(status) ((uint32_t) ((status) >> 4))
761#define {shouty}_WAITABLE_STATUS_BLOCKED (({snake}_waitable_status_t) -1)
762
763typedef enum {snake}_waitable_state {{
764    {shouty}_WAITABLE_COMPLETED,
765    {shouty}_WAITABLE_DROPPED,
766    {shouty}_WAITABLE_CANCELLED,
767}} {snake}_waitable_state_t;
768
769void {snake}_backpressure_inc(void);
770void {snake}_backpressure_dec(void);
771void* {snake}_context_get(void);
772void {snake}_context_set(void*);
773void {snake}_yield(void);
774uint32_t {snake}_yield_cancellable(void);
775            "
776        );
777        uwriteln!(
778            self.src.c_async,
779            r#"
780__attribute__((__import_module__("$root"), __import_name__("[subtask-cancel]")))
781extern uint32_t __subtask_cancel(uint32_t handle);
782
783{snake}_subtask_status_t {snake}_subtask_cancel({snake}_subtask_t subtask) {{
784    return __subtask_cancel(subtask);
785}}
786
787__attribute__((__import_module__("$root"), __import_name__("[subtask-drop]")))
788extern void __subtask_drop(uint32_t handle);
789
790void {snake}_subtask_drop({snake}_subtask_t subtask) {{
791    __subtask_drop(subtask);
792}}
793
794__attribute__((__import_module__("$root"), __import_name__("[waitable-set-new]")))
795extern uint32_t __waitable_set_new(void);
796
797{snake}_waitable_set_t {snake}_waitable_set_new(void) {{
798    return __waitable_set_new();
799}}
800
801__attribute__((__import_module__("$root"), __import_name__("[waitable-join]")))
802extern void __waitable_join(uint32_t, uint32_t);
803
804void {snake}_waitable_join(uint32_t waitable, {snake}_waitable_set_t set) {{
805    __waitable_join(waitable, set);
806}}
807
808__attribute__((__import_module__("$root"), __import_name__("[waitable-set-drop]")))
809extern void __waitable_set_drop(uint32_t);
810
811void {snake}_waitable_set_drop({snake}_waitable_set_t set) {{
812    __waitable_set_drop(set);
813}}
814
815__attribute__((__import_module__("$root"), __import_name__("[waitable-set-wait]")))
816extern uint32_t __waitable_set_wait(uint32_t, uint32_t*);
817__attribute__((__import_module__("$root"), __import_name__("[waitable-set-poll]")))
818extern uint32_t __waitable_set_poll(uint32_t, uint32_t*);
819
820void {snake}_waitable_set_wait({snake}_waitable_set_t set, {snake}_event_t *event) {{
821    event->event = ({snake}_event_code_t) __waitable_set_wait(set, &event->waitable);
822}}
823
824void {snake}_waitable_set_poll({snake}_waitable_set_t set, {snake}_event_t *event) {{
825    event->event = ({snake}_event_code_t) __waitable_set_poll(set, &event->waitable);
826}}
827
828__attribute__((__import_module__("[export]$root"), __import_name__("[task-cancel]")))
829extern void __task_cancel(void);
830
831void {snake}_task_cancel() {{
832    __task_cancel();
833}}
834
835__attribute__((__import_module__("$root"), __import_name__("[backpressure-inc]")))
836extern void __backpressure_inc(void);
837
838void {snake}_backpressure_inc(void) {{
839    __backpressure_inc();
840}}
841
842__attribute__((__import_module__("$root"), __import_name__("[backpressure-dec]")))
843extern void __backpressure_dec(void);
844
845void {snake}_backpressure_dec(void) {{
846    __backpressure_dec();
847}}
848
849__attribute__((__import_module__("$root"), __import_name__("[context-get-0]")))
850extern void* __context_get(void);
851
852void* {snake}_context_get() {{
853    return __context_get();
854}}
855
856__attribute__((__import_module__("$root"), __import_name__("[context-set-0]")))
857extern void __context_set(void*);
858
859void {snake}_context_set(void *val) {{
860    return __context_set(val);
861}}
862
863__attribute__((__import_module__("$root"), __import_name__("[thread-yield]")))
864extern uint32_t __thread_yield(void);
865
866void {snake}_yield(void) {{
867    __thread_yield();
868}}
869
870__attribute__((__import_module__("$root"), __import_name__("[cancellable][thread-yield]")))
871extern uint32_t __thread_yield_cancellable(void);
872
873uint32_t {snake}_yield_cancellable(void) {{
874    return __thread_yield_cancellable();
875}}
876            "#
877        );
878    }
879}
880
881pub fn imported_types_used_by_exported_interfaces(
882    resolve: &Resolve,
883    world: WorldId,
884) -> HashSet<TypeId> {
885    // First build up a set of all types used by exports and all the
886    // exported interfaces.
887    let mut live_export_types = LiveTypes::default();
888    let mut exported_interfaces = HashSet::new();
889    for (_, export) in resolve.worlds[world].exports.iter() {
890        match export {
891            WorldItem::Function(_) => {}
892            WorldItem::Interface { id, .. } => {
893                exported_interfaces.insert(*id);
894                live_export_types.add_interface(resolve, *id)
895            }
896            WorldItem::Type(_) => unreachable!(),
897        }
898    }
899
900    // Using the above sets a set of required import interfaces can be
901    // calculated. This is all referred-to-types that are owned by an
902    // interface that aren't present in an export. Note that the topological
903    // sorting and WIT requirements are what makes this check possible.
904    let mut imports_used = HashSet::new();
905    for ty in live_export_types.iter() {
906        if let TypeOwner::Interface(id) = resolve.types[ty].owner {
907            if !exported_interfaces.contains(&id) {
908                imports_used.insert(id);
909            }
910        }
911    }
912
913    // With the set of imports used that aren't shadowed by exports the set
914    // of types on `self` can now be trimmed. All live types in all the
915    // imports are calculated and then everything except these are removed.
916    let mut live_import_types = LiveTypes::default();
917    for import in imports_used {
918        live_import_types.add_interface(resolve, import);
919    }
920    let live_import_types = live_import_types.iter().collect::<HashSet<_>>();
921    live_import_types
922}
923
924fn is_prim_type(resolve: &Resolve, ty: &Type) -> bool {
925    if let Type::Id(id) = ty {
926        is_prim_type_id(resolve, *id)
927    } else {
928        true
929    }
930}
931
932fn is_prim_type_id(resolve: &Resolve, id: TypeId) -> bool {
933    match &resolve.types[id].kind {
934        TypeDefKind::List(elem) => is_prim_type(resolve, elem),
935
936        TypeDefKind::Option(ty) => is_prim_type(resolve, ty),
937
938        TypeDefKind::Tuple(tuple) => tuple.types.iter().all(|ty| is_prim_type(resolve, ty)),
939
940        TypeDefKind::Type(ty) => is_prim_type(resolve, ty),
941
942        TypeDefKind::Record(_)
943        | TypeDefKind::Resource
944        | TypeDefKind::Handle(_)
945        | TypeDefKind::Flags(_)
946        | TypeDefKind::Variant(_)
947        | TypeDefKind::Enum(_)
948        | TypeDefKind::Result(_)
949        | TypeDefKind::Future(_)
950        | TypeDefKind::Stream(_)
951        | TypeDefKind::Unknown => false,
952        TypeDefKind::FixedSizeList(..) => todo!(),
953    }
954}
955
956pub fn push_ty_name(resolve: &Resolve, ty: &Type, src: &mut String) {
957    match ty {
958        Type::Bool => src.push_str("bool"),
959        Type::Char => src.push_str("char32"),
960        Type::U8 => src.push_str("u8"),
961        Type::S8 => src.push_str("s8"),
962        Type::U16 => src.push_str("u16"),
963        Type::S16 => src.push_str("s16"),
964        Type::U32 => src.push_str("u32"),
965        Type::S32 => src.push_str("s32"),
966        Type::U64 => src.push_str("u64"),
967        Type::S64 => src.push_str("s64"),
968        Type::F32 => src.push_str("f32"),
969        Type::F64 => src.push_str("f64"),
970        Type::String => src.push_str("string"),
971        Type::ErrorContext => todo!(),
972        Type::Id(id) => {
973            let ty = &resolve.types[*id];
974            if let Some(name) = &ty.name {
975                return src.push_str(&name.to_snake_case());
976            }
977            match &ty.kind {
978                TypeDefKind::Type(t) => push_ty_name(resolve, t, src),
979                TypeDefKind::Record(_)
980                | TypeDefKind::Resource
981                | TypeDefKind::Flags(_)
982                | TypeDefKind::Enum(_)
983                | TypeDefKind::Variant(_) => {
984                    unimplemented!()
985                }
986                TypeDefKind::Tuple(t) => {
987                    src.push_str("tuple");
988                    src.push_str(&t.types.len().to_string());
989                    for ty in t.types.iter() {
990                        src.push_str("_");
991                        push_ty_name(resolve, ty, src);
992                    }
993                }
994                TypeDefKind::Option(ty) => {
995                    src.push_str("option_");
996                    push_ty_name(resolve, ty, src);
997                }
998                TypeDefKind::Result(r) => {
999                    src.push_str("result_");
1000                    match &r.ok {
1001                        Some(ty) => push_ty_name(resolve, ty, src),
1002                        None => src.push_str("void"),
1003                    }
1004                    src.push_str("_");
1005                    match &r.err {
1006                        Some(ty) => push_ty_name(resolve, ty, src),
1007                        None => src.push_str("void"),
1008                    }
1009                }
1010                TypeDefKind::List(ty) => {
1011                    src.push_str("list_");
1012                    push_ty_name(resolve, ty, src);
1013                }
1014                TypeDefKind::Future(ty) => {
1015                    src.push_str("future_");
1016                    match ty {
1017                        Some(ty) => push_ty_name(resolve, ty, src),
1018                        None => src.push_str("void"),
1019                    }
1020                }
1021                TypeDefKind::Stream(ty) => {
1022                    src.push_str("stream_");
1023                    match ty {
1024                        Some(ty) => push_ty_name(resolve, ty, src),
1025                        None => src.push_str("void"),
1026                    }
1027                }
1028                TypeDefKind::Handle(Handle::Own(resource)) => {
1029                    src.push_str("own_");
1030                    push_ty_name(resolve, &Type::Id(*resource), src);
1031                }
1032                TypeDefKind::Handle(Handle::Borrow(resource)) => {
1033                    src.push_str("borrow_");
1034                    push_ty_name(resolve, &Type::Id(*resource), src);
1035                }
1036                TypeDefKind::Unknown => unreachable!(),
1037                TypeDefKind::FixedSizeList(..) => todo!(),
1038            }
1039        }
1040    }
1041}
1042
1043pub fn owner_namespace<'a>(
1044    interface: Option<(InterfaceId, &'a WorldKey)>,
1045    in_import: bool,
1046    world: String,
1047    resolve: &Resolve,
1048    id: TypeId,
1049    renamed_interfaces: &HashMap<WorldKey, String>,
1050) -> String {
1051    let ty = &resolve.types[id];
1052    match (ty.owner, interface) {
1053        // If this type is owned by an interface, then we must be generating
1054        // bindings for that interface to proceed.
1055        (TypeOwner::Interface(a), Some((b, key))) if a == b => {
1056            interface_identifier(key, resolve, !in_import, renamed_interfaces)
1057        }
1058        (TypeOwner::Interface(_), None) => unreachable!(),
1059        (TypeOwner::Interface(_), Some(_)) => unreachable!(),
1060
1061        // If this type is owned by a world then we must not be generating
1062        // bindings for an interface.
1063        (TypeOwner::World(_), None) => world.to_snake_case(),
1064        (TypeOwner::World(_), Some(_)) => unreachable!(),
1065
1066        // If this type has no owner then it's an anonymous type. Here it's
1067        // assigned to whatever we happen to be generating bindings for.
1068        (TypeOwner::None, Some((_, key))) => {
1069            interface_identifier(key, resolve, !in_import, renamed_interfaces)
1070        }
1071        (TypeOwner::None, None) => world.to_snake_case(),
1072    }
1073}
1074
1075fn interface_identifier(
1076    interface_id: &WorldKey,
1077    resolve: &Resolve,
1078    in_export: bool,
1079    renamed_interfaces: &HashMap<WorldKey, String>,
1080) -> String {
1081    if let Some(rename) = renamed_interfaces.get(interface_id) {
1082        let mut ns = String::new();
1083        if in_export && matches!(interface_id, WorldKey::Interface(_)) {
1084            ns.push_str("exports_");
1085        }
1086        ns.push_str(rename);
1087        return ns;
1088    }
1089
1090    match interface_id {
1091        WorldKey::Name(name) => name.to_snake_case(),
1092        WorldKey::Interface(id) => {
1093            let mut ns = String::new();
1094            if in_export {
1095                ns.push_str("exports_");
1096            }
1097            let iface = &resolve.interfaces[*id];
1098            let pkg = &resolve.packages[iface.package.unwrap()];
1099            ns.push_str(&pkg.name.namespace.to_snake_case());
1100            ns.push_str("_");
1101            ns.push_str(&pkg.name.name.to_snake_case());
1102            ns.push_str("_");
1103            let pkg_has_multiple_versions = resolve.packages.iter().any(|(_, p)| {
1104                p.name.namespace == pkg.name.namespace
1105                    && p.name.name == pkg.name.name
1106                    && p.name.version != pkg.name.version
1107            });
1108            if pkg_has_multiple_versions {
1109                if let Some(version) = &pkg.name.version {
1110                    let version = version
1111                        .to_string()
1112                        .replace('.', "_")
1113                        .replace('-', "_")
1114                        .replace('+', "_");
1115                    ns.push_str(&version);
1116                    ns.push_str("_");
1117                }
1118            }
1119            ns.push_str(&iface.name.as_ref().unwrap().to_snake_case());
1120            ns
1121        }
1122    }
1123}
1124
1125pub fn c_func_name(
1126    in_import: bool,
1127    resolve: &Resolve,
1128    world: &str,
1129    interface_id: Option<&WorldKey>,
1130    func: &Function,
1131    renamed_interfaces: &HashMap<WorldKey, String>,
1132) -> String {
1133    let mut name = String::new();
1134    match interface_id {
1135        Some(id) => name.push_str(&interface_identifier(
1136            id,
1137            resolve,
1138            !in_import,
1139            renamed_interfaces,
1140        )),
1141        None => {
1142            if !in_import {
1143                name.push_str("exports_");
1144            }
1145            name.push_str(&world.to_snake_case());
1146        }
1147    }
1148    name.push_str("_");
1149    name.push_str(&func.name.to_snake_case().replace('.', "_"));
1150    name
1151}
1152
1153struct InterfaceGenerator<'a> {
1154    src: Source,
1155    in_import: bool,
1156    r#gen: &'a mut C,
1157    resolve: &'a Resolve,
1158    interface: Option<(InterfaceId, &'a WorldKey)>,
1159    wasm_import_module: Option<&'a str>,
1160}
1161
1162impl C {
1163    fn print_intrinsics(&mut self) {
1164        // Note that these intrinsics are declared as `weak` so they can be
1165        // overridden from some other symbol.
1166        self.src.c_fns("\n// Canonical ABI intrinsics");
1167        self.src.c_fns("\n");
1168        self.src.c_fns(
1169            r#"
1170                __attribute__((__weak__, __export_name__("cabi_realloc")))
1171                void *cabi_realloc(void *ptr, size_t old_size, size_t align, size_t new_size) {
1172                    (void) old_size;
1173                    if (new_size == 0) return (void*) align;
1174                    void *ret = realloc(ptr, new_size);
1175                    if (!ret) abort();
1176                    return ret;
1177                }
1178            "#,
1179        );
1180    }
1181}
1182
1183impl Return {
1184    fn return_single(
1185        &mut self,
1186        resolve: &Resolve,
1187        ty: &Type,
1188        orig_ty: &Type,
1189        sig_flattening: bool,
1190    ) {
1191        let id = match ty {
1192            Type::Id(id) => *id,
1193            Type::String => {
1194                self.retptrs.push(*orig_ty);
1195                return;
1196            }
1197            Type::ErrorContext => todo!("return_single for error-context"),
1198            _ => {
1199                self.scalar = Some(Scalar::Type(*orig_ty));
1200                return;
1201            }
1202        };
1203        match &resolve.types[id].kind {
1204            TypeDefKind::Type(t) => return self.return_single(resolve, t, orig_ty, sig_flattening),
1205
1206            // Flags are returned as their bare values, and enums and handles are scalars
1207            TypeDefKind::Flags(_)
1208            | TypeDefKind::Enum(_)
1209            | TypeDefKind::Handle(_)
1210            | TypeDefKind::Future(_)
1211            | TypeDefKind::Stream(_) => {
1212                self.scalar = Some(Scalar::Type(*orig_ty));
1213                return;
1214            }
1215
1216            // Unpack optional returns where a boolean discriminant is
1217            // returned and then the actual type returned is returned
1218            // through a return pointer.
1219            TypeDefKind::Option(ty) => {
1220                if sig_flattening {
1221                    self.scalar = Some(Scalar::OptionBool(*ty));
1222                    self.retptrs.push(*ty);
1223                    return;
1224                }
1225            }
1226
1227            // Unpack a result as a boolean return type, with two
1228            // return pointers for ok and err values
1229            TypeDefKind::Result(r) => {
1230                if sig_flattening {
1231                    if let Some(ok) = r.ok {
1232                        self.retptrs.push(ok);
1233                    }
1234                    if let Some(err) = r.err {
1235                        self.retptrs.push(err);
1236                    }
1237                    self.scalar = Some(Scalar::ResultBool(r.ok, r.err));
1238                    return;
1239                }
1240            }
1241
1242            // These types are always returned indirectly.
1243            TypeDefKind::Tuple(_)
1244            | TypeDefKind::Record(_)
1245            | TypeDefKind::List(_)
1246            | TypeDefKind::Variant(_) => {}
1247
1248            TypeDefKind::Resource => todo!("return_single for resource"),
1249            TypeDefKind::Unknown => unreachable!(),
1250            TypeDefKind::FixedSizeList(..) => todo!(),
1251        }
1252
1253        self.retptrs.push(*orig_ty);
1254    }
1255}
1256
1257impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
1258    fn resolve(&self) -> &'a Resolve {
1259        self.resolve
1260    }
1261
1262    fn type_record(&mut self, id: TypeId, _name: &str, record: &Record, docs: &Docs) {
1263        self.src.h_defs("\n");
1264        self.docs(docs, SourceType::HDefs);
1265        self.start_typedef_struct(id);
1266        for field in record.fields.iter() {
1267            self.docs(&field.docs, SourceType::HDefs);
1268            self.print_ty(SourceType::HDefs, &field.ty);
1269            self.src.h_defs(" ");
1270            self.src.h_defs(&to_c_ident(&field.name));
1271            self.src.h_defs(";\n");
1272        }
1273        self.finish_typedef_struct(id);
1274    }
1275
1276    fn type_resource(&mut self, id: TypeId, name: &str, _docs: &Docs) {
1277        let ns = self.owner_namespace(id);
1278        let snake = name.to_snake_case();
1279        let mut own = ns.clone();
1280        let mut borrow = own.clone();
1281        own.push_str("_own");
1282        borrow.push_str("_borrow");
1283        own.push_str("_");
1284        borrow.push_str("_");
1285        own.push_str(&snake);
1286        borrow.push_str(&snake);
1287        own.push_str("_t");
1288        borrow.push_str("_t");
1289
1290        // All resources, whether or not they're imported or exported, get the
1291        // ability to drop handles.
1292        self.src.h_helpers(&format!(
1293            "
1294extern void {ns}_{snake}_drop_own({own} handle);
1295            "
1296        ));
1297        let import_module = if self.in_import {
1298            self.wasm_import_module.unwrap().to_string()
1299        } else {
1300            let module = match self.interface {
1301                Some((_, key)) => self.resolve.name_world_key(key),
1302                None => unimplemented!("resource exports from worlds"),
1303            };
1304            format!("[export]{module}")
1305        };
1306
1307        let drop_fn = format!("__wasm_import_{ns}_{snake}_drop");
1308
1309        self.src.c_helpers(&format!(
1310            r#"
1311__attribute__((__import_module__("{import_module}"), __import_name__("[resource-drop]{name}")))
1312extern void {drop_fn}(int32_t handle);
1313
1314void {ns}_{snake}_drop_own({own} handle) {{
1315    {drop_fn}(handle.__handle);
1316}}
1317            "#
1318        ));
1319
1320        // All resources, whether or not they're imported or exported, have an
1321        // handle-index-based representation for "own" handles.
1322        self.src.h_defs(&format!(
1323            "\ntypedef struct {own} {{\nint32_t __handle;\n}} {own};\n"
1324        ));
1325
1326        if self.in_import {
1327            // For imported resources borrowed handles are represented the same
1328            // way as owned handles. They're given a unique type, however, to
1329            // prevent type confusion at runtime in theory.
1330            self.src.h_defs(&format!(
1331                "\ntypedef struct {borrow} {{\nint32_t __handle;\n}} {borrow};\n"
1332            ));
1333
1334            // Explicit borrow dropping is not required if autodrop is enabled.
1335            if !self.autodrop_enabled() {
1336                // As we have two different types for owned vs borrowed resources,
1337                // but owns and borrows are dropped using the same intrinsic we
1338                // also generate a version of the drop function for borrows that we
1339                // possibly acquire through our exports.
1340                self.src.h_helpers(&format!(
1341                    "\nextern void {ns}_{snake}_drop_borrow({borrow} handle);\n"
1342                ));
1343
1344                self.src.c_helpers(&format!(
1345                    "
1346void {ns}_{snake}_drop_borrow({borrow} handle) {{
1347    __wasm_import_{ns}_{snake}_drop(handle.__handle);
1348}}
1349                "
1350                ));
1351            }
1352
1353            // To handle the two types generated for borrow/own this helper
1354            // function enables converting an own handle to a borrow handle
1355            // which will have the same index internally.
1356            self.src.h_helpers(&format!(
1357                "
1358extern {borrow} {ns}_borrow_{snake}({own} handle);
1359                "
1360            ));
1361
1362            self.src.c_helpers(&format!(
1363                r#"
1364{borrow} {ns}_borrow_{snake}({own} arg) {{
1365    return ({borrow}) {{ arg.__handle }};
1366}}
1367                "#
1368            ));
1369        } else {
1370            // For exported resources first generate a typedef that the user
1371            // will be required to fill in. This is an empty struct.
1372            self.src.h_defs("\n");
1373            self.src.h_defs("typedef struct ");
1374            let ty_name = self.r#gen.type_names[&id].clone();
1375            self.src.h_defs(&ty_name);
1376            self.src.h_defs(" ");
1377            self.print_typedef_target(id);
1378            let (_, key) = self.interface.unwrap();
1379            let module = self.resolve.name_world_key(key);
1380
1381            // Exported resources use a different representation than imports
1382            // for borrows which is a raw pointer to the struct declared just
1383            // above.
1384            self.src
1385                .h_defs(&format!("\ntypedef {ty_name}* {borrow};\n"));
1386
1387            // Exported resources are defined by this module which means they
1388            // get access to more intrinsics:
1389            //
1390            // * construction of a resource (rep to handle)
1391            // * extraction of the representation of a resource (handle to rep)
1392            //
1393            // Additionally users must define a destructor for this resource, so
1394            // declare its prototype here.
1395            self.src.h_helpers(&format!(
1396                "
1397extern {own} {ns}_{snake}_new({ty_name} *rep);
1398extern {ty_name}* {ns}_{snake}_rep({own} handle);
1399void {ns}_{snake}_destructor({ty_name} *rep);
1400                "
1401            ));
1402
1403            self.src.c_helpers(&format!(
1404                r#"
1405__attribute__(( __import_module__("[export]{module}"), __import_name__("[resource-new]{name}")))
1406extern int32_t __wasm_import_{ns}_{snake}_new(int32_t);
1407
1408__attribute__((__import_module__("[export]{module}"), __import_name__("[resource-rep]{name}")))
1409extern int32_t __wasm_import_{ns}_{snake}_rep(int32_t);
1410
1411{own} {ns}_{snake}_new({ty_name} *rep) {{
1412    return ({own}) {{ __wasm_import_{ns}_{snake}_new((int32_t) rep) }};
1413}}
1414
1415{ty_name}* {ns}_{snake}_rep({own} handle) {{
1416    return ({ns}_{snake}_t*) __wasm_import_{ns}_{snake}_rep(handle.__handle);
1417}}
1418
1419__attribute__((__export_name__("{module}#[dtor]{snake}")))
1420void __wasm_export_{ns}_{snake}_dtor({ns}_{snake}_t* arg) {{
1421    {ns}_{snake}_destructor(arg);
1422}}
1423                "#
1424            ));
1425        }
1426
1427        self.r#gen.resources.insert(
1428            id,
1429            ResourceInfo {
1430                own,
1431                borrow,
1432                direction: if self.in_import {
1433                    Direction::Import
1434                } else {
1435                    Direction::Export
1436                },
1437                drop_fn,
1438            },
1439        );
1440    }
1441
1442    fn type_tuple(&mut self, id: TypeId, _name: &str, tuple: &Tuple, docs: &Docs) {
1443        self.src.h_defs("\n");
1444        self.docs(docs, SourceType::HDefs);
1445        self.start_typedef_struct(id);
1446        for (i, ty) in tuple.types.iter().enumerate() {
1447            self.print_ty(SourceType::HDefs, ty);
1448            uwriteln!(self.src.h_defs, " f{i};");
1449        }
1450        self.finish_typedef_struct(id);
1451    }
1452
1453    fn type_flags(&mut self, id: TypeId, name: &str, flags: &Flags, docs: &Docs) {
1454        self.src.h_defs("\n");
1455        self.docs(docs, SourceType::HDefs);
1456        self.src.h_defs("typedef ");
1457        let repr = flags_repr(flags);
1458        self.src.h_defs(int_repr(repr));
1459        self.src.h_defs(" ");
1460        self.print_typedef_target(id);
1461
1462        if flags.flags.len() > 0 {
1463            self.src.h_defs("\n");
1464        }
1465        let ns = self.owner_namespace(id).to_shouty_snake_case();
1466        for (i, flag) in flags.flags.iter().enumerate() {
1467            self.docs(&flag.docs, SourceType::HDefs);
1468            uwriteln!(
1469                self.src.h_defs,
1470                "#define {ns}_{}_{} (1 << {i})",
1471                name.to_shouty_snake_case(),
1472                flag.name.to_shouty_snake_case(),
1473            );
1474        }
1475    }
1476
1477    fn type_variant(&mut self, id: TypeId, name: &str, variant: &Variant, docs: &Docs) {
1478        self.src.h_defs("\n");
1479        self.docs(docs, SourceType::HDefs);
1480        self.start_typedef_struct(id);
1481        self.src.h_defs(int_repr(variant.tag()));
1482        self.src.h_defs(" tag;\n");
1483
1484        let cases_with_data = Vec::from_iter(
1485            variant
1486                .cases
1487                .iter()
1488                .filter_map(|case| case.ty.as_ref().map(|ty| (&case.name, ty))),
1489        );
1490
1491        if !cases_with_data.is_empty() {
1492            self.src.h_defs("union {\n");
1493            for (name, ty) in cases_with_data {
1494                self.print_ty(SourceType::HDefs, ty);
1495                self.src.h_defs(" ");
1496                self.src.h_defs(&to_c_ident(name));
1497                self.src.h_defs(";\n");
1498            }
1499            self.src.h_defs("} val;\n");
1500        }
1501        self.finish_typedef_struct(id);
1502
1503        if variant.cases.len() > 0 {
1504            self.src.h_defs("\n");
1505        }
1506        let ns = self.owner_namespace(id).to_shouty_snake_case();
1507        for (i, case) in variant.cases.iter().enumerate() {
1508            self.docs(&case.docs, SourceType::HDefs);
1509            uwriteln!(
1510                self.src.h_defs,
1511                "#define {ns}_{}_{} {i}",
1512                name.to_shouty_snake_case(),
1513                case.name.to_shouty_snake_case(),
1514            );
1515        }
1516    }
1517
1518    fn type_option(&mut self, id: TypeId, _name: &str, payload: &Type, docs: &Docs) {
1519        self.src.h_defs("\n");
1520        self.docs(docs, SourceType::HDefs);
1521        self.start_typedef_struct(id);
1522        self.src.h_defs("bool is_some;\n");
1523        self.print_ty(SourceType::HDefs, payload);
1524        self.src.h_defs(" val;\n");
1525        self.finish_typedef_struct(id);
1526    }
1527
1528    fn type_result(&mut self, id: TypeId, _name: &str, result: &Result_, docs: &Docs) {
1529        self.src.h_defs("\n");
1530        self.docs(docs, SourceType::HDefs);
1531        self.start_typedef_struct(id);
1532        self.src.h_defs("bool is_err;\n");
1533        if result.ok.is_some() || result.err.is_some() {
1534            self.src.h_defs("union {\n");
1535            if let Some(ok) = result.ok.as_ref() {
1536                self.print_ty(SourceType::HDefs, ok);
1537                self.src.h_defs(" ok;\n");
1538            }
1539            if let Some(err) = result.err.as_ref() {
1540                self.print_ty(SourceType::HDefs, err);
1541                self.src.h_defs(" err;\n");
1542            }
1543            self.src.h_defs("} val;\n");
1544        }
1545        self.finish_typedef_struct(id);
1546    }
1547
1548    fn type_enum(&mut self, id: TypeId, name: &str, enum_: &Enum, docs: &Docs) {
1549        uwrite!(self.src.h_defs, "\n");
1550        self.docs(docs, SourceType::HDefs);
1551        let int_t = int_repr(enum_.tag());
1552        uwrite!(self.src.h_defs, "typedef {int_t} ");
1553        self.print_typedef_target(id);
1554
1555        if enum_.cases.len() > 0 {
1556            self.src.h_defs("\n");
1557        }
1558        let ns = self.owner_namespace(id).to_shouty_snake_case();
1559        for (i, case) in enum_.cases.iter().enumerate() {
1560            self.docs(&case.docs, SourceType::HDefs);
1561            uwriteln!(
1562                self.src.h_defs,
1563                "#define {ns}_{}_{} {i}",
1564                name.to_shouty_snake_case(),
1565                case.name.to_shouty_snake_case(),
1566            );
1567        }
1568    }
1569
1570    fn type_alias(&mut self, id: TypeId, _name: &str, ty: &Type, docs: &Docs) {
1571        // we should skip generating `typedef` for `Resource` types because they aren't even
1572        // defined anywhere, not even in `type_resource`. Only its `Handle` types are defined.
1573        // The aliasing handle types are defined in `define_anonymous_type`.
1574        let target = dealias(self.resolve, id);
1575        if matches!(&self.resolve.types[target].kind, TypeDefKind::Resource) {
1576            return;
1577        }
1578
1579        self.src.h_defs("\n");
1580        self.docs(docs, SourceType::HDefs);
1581        self.src.h_defs("typedef ");
1582        self.print_ty(SourceType::HDefs, ty);
1583        self.src.h_defs(" ");
1584        self.print_typedef_target(id);
1585    }
1586
1587    fn type_list(&mut self, id: TypeId, _name: &str, ty: &Type, docs: &Docs) {
1588        self.src.h_defs("\n");
1589        self.docs(docs, SourceType::HDefs);
1590        self.start_typedef_struct(id);
1591        self.print_ty(SourceType::HDefs, ty);
1592        self.src.h_defs(" *ptr;\n");
1593        self.src.h_defs("size_t len;\n");
1594        self.finish_typedef_struct(id);
1595    }
1596
1597    fn type_future(&mut self, id: TypeId, _name: &str, _ty: &Option<Type>, docs: &Docs) {
1598        self.src.h_defs("\n");
1599        self.docs(docs, SourceType::HDefs);
1600        self.src.h_defs("\ntypedef uint32_t ");
1601        self.print_typedef_target(id);
1602    }
1603
1604    fn type_stream(&mut self, id: TypeId, _name: &str, _ty: &Option<Type>, docs: &Docs) {
1605        self.src.h_defs("\n");
1606        self.docs(docs, SourceType::HDefs);
1607        self.src.h_defs("\ntypedef uint32_t ");
1608        self.print_typedef_target(id);
1609    }
1610
1611    fn type_builtin(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
1612        let _ = (id, name, ty, docs);
1613    }
1614}
1615
1616impl<'a> wit_bindgen_core::AnonymousTypeGenerator<'a> for InterfaceGenerator<'a> {
1617    fn resolve(&self) -> &'a Resolve {
1618        self.resolve
1619    }
1620
1621    fn anonymous_type_handle(&mut self, id: TypeId, handle: &Handle, _docs: &Docs) {
1622        self.src.h_defs("\ntypedef ");
1623        let resource = match handle {
1624            Handle::Borrow(id) | Handle::Own(id) => id,
1625        };
1626        let info = &self.r#gen.resources[&dealias(self.resolve, *resource)];
1627        match handle {
1628            Handle::Borrow(_) => self.src.h_defs(&info.borrow),
1629            Handle::Own(_) => self.src.h_defs(&info.own),
1630        }
1631        self.src.h_defs(" ");
1632        self.print_typedef_target(id);
1633    }
1634
1635    fn anonymous_type_tuple(&mut self, id: TypeId, ty: &Tuple, _docs: &Docs) {
1636        self.src.h_defs("\ntypedef ");
1637        self.src.h_defs("struct {\n");
1638        for (i, t) in ty.types.iter().enumerate() {
1639            let ty = self.r#gen.type_name(t);
1640            uwriteln!(self.src.h_defs, "{ty} f{i};");
1641        }
1642        self.src.h_defs("}");
1643        self.src.h_defs(" ");
1644        self.print_typedef_target(id);
1645    }
1646
1647    fn anonymous_type_option(&mut self, id: TypeId, ty: &Type, _docs: &Docs) {
1648        self.src.h_defs("\ntypedef ");
1649        self.src.h_defs("struct {\n");
1650        self.src.h_defs("bool is_some;\n");
1651        let ty = self.r#gen.type_name(ty);
1652        uwriteln!(self.src.h_defs, "{ty} val;");
1653        self.src.h_defs("}");
1654        self.src.h_defs(" ");
1655        self.print_typedef_target(id);
1656    }
1657
1658    fn anonymous_type_result(&mut self, id: TypeId, ty: &Result_, _docs: &Docs) {
1659        self.src.h_defs("\ntypedef ");
1660        self.src.h_defs(
1661            "struct {
1662                bool is_err;
1663            ",
1664        );
1665        let ok_ty = ty.ok.as_ref();
1666        let err_ty = ty.err.as_ref();
1667        if ok_ty.is_some() || err_ty.is_some() {
1668            self.src.h_defs("union {\n");
1669            if let Some(ok) = ok_ty {
1670                let ty = self.r#gen.type_name(ok);
1671                uwriteln!(self.src.h_defs, "{ty} ok;");
1672            }
1673            if let Some(err) = err_ty {
1674                let ty = self.r#gen.type_name(err);
1675                uwriteln!(self.src.h_defs, "{ty} err;");
1676            }
1677            self.src.h_defs("} val;\n");
1678        }
1679        self.src.h_defs("}");
1680        self.src.h_defs(" ");
1681        self.print_typedef_target(id);
1682    }
1683
1684    fn anonymous_type_list(&mut self, id: TypeId, ty: &Type, _docs: &Docs) {
1685        self.src.h_defs("\ntypedef ");
1686        self.src.h_defs("struct {\n");
1687        let ty = self.r#gen.type_name(ty);
1688        uwriteln!(self.src.h_defs, "{ty} *ptr;");
1689        self.src.h_defs("size_t len;\n");
1690        self.src.h_defs("}");
1691        self.src.h_defs(" ");
1692        self.print_typedef_target(id);
1693    }
1694
1695    fn anonymous_type_future(&mut self, id: TypeId, _ty: &Option<Type>, _docs: &Docs) {
1696        self.src.h_defs("\ntypedef uint32_t ");
1697        self.print_typedef_target(id);
1698    }
1699
1700    fn anonymous_type_stream(&mut self, id: TypeId, _ty: &Option<Type>, _docs: &Docs) {
1701        self.src.h_defs("\ntypedef uint32_t ");
1702        self.print_typedef_target(id);
1703    }
1704
1705    fn anonymous_type_type(&mut self, _id: TypeId, _ty: &Type, _docs: &Docs) {
1706        todo!("print_anonymous_type for type");
1707    }
1708}
1709
1710pub enum CTypeNameInfo<'a> {
1711    Named { name: &'a str },
1712    Anonymous { is_prim: bool },
1713}
1714
1715/// Generate the type part of a c identifier, missing the namespace and the `_t` suffix.
1716/// Additionally return a `CTypeNameInfo` that describes what sort of name has been produced.
1717pub fn gen_type_name(resolve: &Resolve, ty: TypeId) -> (CTypeNameInfo<'_>, String) {
1718    let mut encoded = String::new();
1719    push_ty_name(resolve, &Type::Id(ty), &mut encoded);
1720    let info = if let Some(name) = &resolve.types[ty].name {
1721        CTypeNameInfo::Named {
1722            name: name.as_ref(),
1723        }
1724    } else {
1725        CTypeNameInfo::Anonymous {
1726            is_prim: is_prim_type_id(resolve, ty),
1727        }
1728    };
1729
1730    (info, encoded)
1731}
1732
1733impl InterfaceGenerator<'_> {
1734    fn define_interface_types(&mut self, id: InterfaceId) {
1735        let mut live = LiveTypes::default();
1736        live.add_interface(self.resolve, id);
1737        self.define_live_types(live);
1738    }
1739
1740    fn define_function_types(&mut self, funcs: &[(&str, &Function)]) {
1741        let mut live = LiveTypes::default();
1742        for (_, func) in funcs {
1743            live.add_func(self.resolve, func);
1744        }
1745        self.define_live_types(live);
1746    }
1747
1748    fn define_live_types(&mut self, live: LiveTypes) {
1749        for ty in live.iter() {
1750            if self.r#gen.type_names.contains_key(&ty) {
1751                continue;
1752            }
1753
1754            let (info, encoded) = gen_type_name(&self.resolve, ty);
1755            match info {
1756                CTypeNameInfo::Named { name } => {
1757                    let typedef_name = format!("{}_{encoded}_t", self.owner_namespace(ty));
1758                    let prev = self.r#gen.type_names.insert(ty, typedef_name.clone());
1759                    assert!(prev.is_none());
1760
1761                    self.define_type(name, ty)
1762                }
1763
1764                CTypeNameInfo::Anonymous { is_prim } => {
1765                    let (defined, name) = if is_prim {
1766                        let namespace = self.r#gen.world.to_snake_case();
1767                        let name = format!("{namespace}_{encoded}_t");
1768                        let new_prim = self.r#gen.prim_names.insert(name.clone());
1769                        (!new_prim, name)
1770                    } else {
1771                        let namespace = self.owner_namespace(ty);
1772                        (false, format!("{namespace}_{encoded}_t"))
1773                    };
1774
1775                    let prev = self.r#gen.type_names.insert(ty, name);
1776                    assert!(prev.is_none());
1777
1778                    if defined {
1779                        continue;
1780                    }
1781
1782                    let kind = &self.resolve.types[ty].kind;
1783                    if let TypeDefKind::Handle(handle) = kind {
1784                        let resource = match handle {
1785                            Handle::Borrow(id) | Handle::Own(id) => id,
1786                        };
1787                        let origin = dealias(self.resolve, *resource);
1788                        if origin == *resource {
1789                            continue;
1790                        }
1791                    }
1792
1793                    self.define_anonymous_type(ty)
1794                }
1795            }
1796
1797            self.define_dtor(ty);
1798        }
1799    }
1800
1801    fn define_dtor(&mut self, id: TypeId) {
1802        let h_helpers_start = self.src.h_helpers.len();
1803        let c_helpers_start = self.src.c_helpers.len();
1804
1805        let name = self.r#gen.type_names[&id].clone();
1806        let prefix = name.strip_suffix("_t").unwrap();
1807
1808        self.src
1809            .h_helpers(&format!("\nvoid {prefix}_free({name} *ptr);\n"));
1810        self.src
1811            .c_helpers(&format!("\nvoid {prefix}_free({name} *ptr) {{\n"));
1812        let c_helpers_body_start = self.src.c_helpers.len();
1813        match &self.resolve.types[id].kind {
1814            TypeDefKind::Type(t) => self.free(t, "ptr"),
1815
1816            TypeDefKind::Flags(_) => {}
1817            TypeDefKind::Enum(_) => {}
1818
1819            TypeDefKind::Record(r) => {
1820                for field in r.fields.iter() {
1821                    self.free(&field.ty, &format!("&ptr->{}", to_c_ident(&field.name)));
1822                }
1823            }
1824
1825            TypeDefKind::Tuple(t) => {
1826                for (i, ty) in t.types.iter().enumerate() {
1827                    self.free(ty, &format!("&ptr->f{i}"));
1828                }
1829            }
1830
1831            TypeDefKind::List(t) => {
1832                self.src.c_helpers("size_t list_len = ptr->len;\n");
1833                uwriteln!(self.src.c_helpers, "if (list_len > 0) {{");
1834                let mut t_name = String::new();
1835                self.r#gen.push_type_name(t, &mut t_name);
1836                self.src
1837                    .c_helpers(&format!("{t_name} *list_ptr = ptr->ptr;\n"));
1838                self.src
1839                    .c_helpers("for (size_t i = 0; i < list_len; i++) {\n");
1840                self.free(t, "&list_ptr[i]");
1841                self.src.c_helpers("}\n");
1842                uwriteln!(self.src.c_helpers, "free(list_ptr);");
1843                uwriteln!(self.src.c_helpers, "}}");
1844            }
1845
1846            TypeDefKind::Variant(v) => {
1847                self.src.c_helpers("switch ((int32_t) ptr->tag) {\n");
1848                for (i, case) in v.cases.iter().enumerate() {
1849                    if let Some(ty) = &case.ty {
1850                        uwriteln!(self.src.c_helpers, "case {}: {{", i);
1851                        let expr = format!("&ptr->val.{}", to_c_ident(&case.name));
1852                        self.free(ty, &expr);
1853                        self.src.c_helpers("break;\n");
1854                        self.src.c_helpers("}\n");
1855                    }
1856                }
1857                self.src.c_helpers("}\n");
1858            }
1859
1860            TypeDefKind::Option(t) => {
1861                self.src.c_helpers("if (ptr->is_some) {\n");
1862                self.free(t, "&ptr->val");
1863                self.src.c_helpers("}\n");
1864            }
1865
1866            TypeDefKind::Result(r) => {
1867                self.src.c_helpers("if (!ptr->is_err) {\n");
1868                if let Some(ok) = &r.ok {
1869                    self.free(ok, "&ptr->val.ok");
1870                }
1871                if let Some(err) = &r.err {
1872                    self.src.c_helpers("} else {\n");
1873                    self.free(err, "&ptr->val.err");
1874                }
1875                self.src.c_helpers("}\n");
1876            }
1877            TypeDefKind::Future(_) | TypeDefKind::Stream(_) => {
1878                self.free(&Type::Id(id), "*ptr");
1879            }
1880            TypeDefKind::Resource => {}
1881            TypeDefKind::Handle(Handle::Borrow(id) | Handle::Own(id)) => {
1882                self.free(&Type::Id(*id), "*ptr");
1883            }
1884            TypeDefKind::Unknown => unreachable!(),
1885            TypeDefKind::FixedSizeList(..) => todo!(),
1886        }
1887        if c_helpers_body_start == self.src.c_helpers.len() {
1888            self.src.c_helpers.as_mut_string().truncate(c_helpers_start);
1889            self.src.h_helpers.as_mut_string().truncate(h_helpers_start);
1890            return;
1891        }
1892        self.src.c_helpers("}\n");
1893        self.r#gen.dtor_funcs.insert(id, format!("{prefix}_free"));
1894    }
1895
1896    fn free(&mut self, ty: &Type, expr: &str) {
1897        match ty {
1898            Type::Id(id) => {
1899                if let Some(dtor) = self.r#gen.dtor_funcs.get(&id) {
1900                    self.src.c_helpers(&format!("{dtor}({expr});\n"));
1901                }
1902            }
1903            Type::String => {
1904                let snake = self.r#gen.world.to_snake_case();
1905                self.src
1906                    .c_helpers(&format!("{snake}_string_free({expr});\n"));
1907            }
1908            Type::Bool
1909            | Type::U8
1910            | Type::S8
1911            | Type::U16
1912            | Type::S16
1913            | Type::U32
1914            | Type::S32
1915            | Type::U64
1916            | Type::S64
1917            | Type::F32
1918            | Type::F64
1919            | Type::Char => {}
1920            Type::ErrorContext => todo!("error context free"),
1921        }
1922    }
1923
1924    fn c_func_name(&self, interface_id: Option<&WorldKey>, func: &Function) -> String {
1925        c_func_name(
1926            self.in_import,
1927            self.resolve,
1928            &self.r#gen.world,
1929            interface_id,
1930            func,
1931            &self.r#gen.renamed_interfaces,
1932        )
1933    }
1934
1935    fn import(&mut self, interface_name: Option<&WorldKey>, func: &Function) {
1936        let async_ = self
1937            .r#gen
1938            .opts
1939            .async_
1940            .is_async(self.resolve, interface_name, func, true);
1941        if async_ {
1942            self.r#gen.needs_async = true;
1943        }
1944
1945        self.docs(&func.docs, SourceType::HFns);
1946        let (variant, import_prefix) = if async_ {
1947            (AbiVariant::GuestImportAsync, "[async-lower]")
1948        } else {
1949            (AbiVariant::GuestImport, "")
1950        };
1951        let sig = self.resolve.wasm_signature(variant, func);
1952
1953        self.src.c_fns("\n");
1954
1955        // In the private C file, print a function declaration which is the
1956        // actual wasm import that we'll be calling, and this has the raw wasm
1957        // signature.
1958        uwriteln!(
1959            self.src.c_fns,
1960            "__attribute__((__import_module__(\"{}\"), __import_name__(\"{import_prefix}{}\")))",
1961            match interface_name {
1962                Some(name) => self.resolve.name_world_key(name),
1963                None => "$root".to_string(),
1964            },
1965            func.name
1966        );
1967        let name = self.c_func_name(interface_name, func);
1968        let import_name = self.r#gen.names.tmp(&format!("__wasm_import_{name}",));
1969        self.src.c_fns("extern ");
1970        match sig.results.len() {
1971            0 => self.src.c_fns("void"),
1972            1 => self.src.c_fns(wasm_type(sig.results[0])),
1973            _ => unimplemented!("multi-value return not supported"),
1974        }
1975        self.src.c_fns(" ");
1976        self.src.c_fns(&import_name);
1977        self.src.c_fns("(");
1978        for (i, param) in sig.params.iter().enumerate() {
1979            if i > 0 {
1980                self.src.c_fns(", ");
1981            }
1982            self.src.c_fns(wasm_type(*param));
1983        }
1984        if sig.params.len() == 0 {
1985            self.src.c_fns("void");
1986        }
1987        self.src.c_fns(");\n");
1988
1989        // Print the public facing signature into the header, and since that's
1990        // what we are defining also print it into the C file.
1991        self.src.h_fns("extern ");
1992        let c_sig = self.print_sig(interface_name, func, &sig, async_);
1993        self.src.c_adapters("\n");
1994        self.src.c_adapters(&c_sig.sig);
1995        self.src.c_adapters(" {\n");
1996
1997        if async_ {
1998            self.import_body_async(func, c_sig, &sig, &import_name);
1999        } else {
2000            self.import_body_sync(func, c_sig, &import_name);
2001        }
2002
2003        self.src.c_adapters("}\n");
2004
2005        self.generate_async_futures_and_streams("", func, interface_name);
2006    }
2007
2008    fn import_body_sync(&mut self, func: &Function, c_sig: CSig, import_name: &str) {
2009        // construct optional adapters from maybe pointers to real optional
2010        // structs internally
2011        let mut optional_adapters = String::from("");
2012        if !self.r#gen.opts.no_sig_flattening {
2013            for (i, (_, param)) in c_sig.params.iter().enumerate() {
2014                let ty = &func.params[i].1;
2015                if let Type::Id(id) = ty {
2016                    if let TypeDefKind::Option(_) = &self.resolve.types[*id].kind {
2017                        let ty = self.r#gen.type_name(ty);
2018                        uwrite!(
2019                            optional_adapters,
2020                            "{ty} {param};
2021                            {param}.is_some = maybe_{param} != NULL;"
2022                        );
2023                        uwriteln!(
2024                            optional_adapters,
2025                            "if (maybe_{param}) {{
2026                                {param}.val = *maybe_{param};
2027                            }}",
2028                        );
2029                    }
2030                }
2031            }
2032        }
2033
2034        let mut f = FunctionBindgen::new(self, c_sig, &import_name);
2035        for (pointer, param) in f.sig.params.iter() {
2036            if *pointer {
2037                f.params.push(format!("*{}", param));
2038            } else {
2039                f.params.push(param.clone());
2040            }
2041        }
2042        for ptr in f.sig.retptrs.iter() {
2043            f.locals.insert(ptr).unwrap();
2044        }
2045        f.src.push_str(&optional_adapters);
2046        abi::call(
2047            f.r#gen.resolve,
2048            AbiVariant::GuestImport,
2049            LiftLower::LowerArgsLiftResults,
2050            func,
2051            &mut f,
2052            false,
2053        );
2054
2055        let FunctionBindgen {
2056            src,
2057            import_return_pointer_area_size,
2058            import_return_pointer_area_align,
2059            ..
2060        } = f;
2061
2062        if !import_return_pointer_area_size.is_empty() {
2063            self.src.c_adapters(&format!(
2064                "\
2065                    __attribute__((__aligned__({})))
2066                    uint8_t ret_area[{}];
2067                ",
2068                import_return_pointer_area_align.format(POINTER_SIZE_EXPRESSION),
2069                import_return_pointer_area_size.format(POINTER_SIZE_EXPRESSION),
2070            ));
2071        }
2072
2073        self.src.c_adapters(&String::from(src));
2074    }
2075
2076    fn import_body_async(
2077        &mut self,
2078        func: &Function,
2079        c_sig: CSig,
2080        wasm_sig: &WasmSignature,
2081        import_name: &str,
2082    ) {
2083        let mut params = Vec::new();
2084        if wasm_sig.indirect_params {
2085            params.push(format!("(uint8_t*) {}", c_sig.params[0].1));
2086        } else {
2087            let mut f = FunctionBindgen::new(self, c_sig.clone(), "INVALID");
2088            for (i, (_, ty)) in func.params.iter().enumerate() {
2089                let param = &c_sig.params[i].1;
2090                params.extend(abi::lower_flat(f.r#gen.resolve, &mut f, param.clone(), ty));
2091            }
2092            f.r#gen.src.c_adapters.push_str(&f.src);
2093        }
2094        if func.result.is_some() {
2095            params.push(format!("(uint8_t*) {}", c_sig.params.last().unwrap().1));
2096        }
2097        uwriteln!(
2098            self.src.c_adapters,
2099            "return {import_name}({});",
2100            params.join(", "),
2101        );
2102    }
2103
2104    fn export(&mut self, func: &Function, interface_name: Option<&WorldKey>) {
2105        let async_ = self
2106            .r#gen
2107            .opts
2108            .async_
2109            .is_async(self.resolve, interface_name, func, false);
2110
2111        let (variant, prefix) = if async_ {
2112            self.r#gen.needs_async = true;
2113            (AbiVariant::GuestExportAsync, "[async-lift]")
2114        } else {
2115            (AbiVariant::GuestExport, "")
2116        };
2117
2118        let sig = self.resolve.wasm_signature(variant, func);
2119
2120        self.src.c_fns("\n");
2121
2122        let core_module_name = interface_name.map(|s| self.resolve.name_world_key(s));
2123        let export_name = func.legacy_core_export_name(core_module_name.as_deref());
2124
2125        // Print the actual header for this function into the header file, and
2126        // it's what we'll be calling.
2127        let h_sig = self.print_sig(interface_name, func, &sig, async_);
2128
2129        // Generate, in the C source file, the raw wasm signature that has the
2130        // canonical ABI.
2131        uwriteln!(
2132            self.src.c_adapters,
2133            "\n__attribute__((__export_name__(\"{prefix}{export_name}\")))"
2134        );
2135        let name = self.c_func_name(interface_name, func);
2136        let import_name = self.r#gen.names.tmp(&format!("__wasm_export_{name}"));
2137
2138        let mut f = FunctionBindgen::new(self, h_sig, &import_name);
2139        match sig.results.len() {
2140            0 => f.r#gen.src.c_adapters("void"),
2141            1 => f.r#gen.src.c_adapters(wasm_type(sig.results[0])),
2142            _ => unimplemented!("multi-value return not supported"),
2143        }
2144        f.r#gen.src.c_adapters(" ");
2145        f.r#gen.src.c_adapters(&import_name);
2146        f.r#gen.src.c_adapters("(");
2147        for (i, param) in sig.params.iter().enumerate() {
2148            if i > 0 {
2149                f.r#gen.src.c_adapters(", ");
2150            }
2151            let name = f.locals.tmp("arg");
2152            uwrite!(f.r#gen.src.c_adapters, "{} {}", wasm_type(*param), name);
2153            f.params.push(name);
2154        }
2155        if sig.params.len() == 0 {
2156            f.r#gen.src.c_adapters("void");
2157        }
2158        f.r#gen.src.c_adapters(") {\n");
2159
2160        // Perform all lifting/lowering and append it to our src.
2161        abi::call(
2162            f.r#gen.resolve,
2163            variant,
2164            LiftLower::LiftArgsLowerResults,
2165            func,
2166            &mut f,
2167            async_,
2168        );
2169        let FunctionBindgen {
2170            src,
2171            deferred_task_return,
2172            ..
2173        } = f;
2174        self.src.c_adapters(&src);
2175        self.src.c_adapters("}\n");
2176
2177        if async_ {
2178            let snake = self.r#gen.world.to_snake_case();
2179            let return_ty = match &func.result {
2180                Some(ty) => format!("{} ret", self.r#gen.type_name(ty)),
2181                None => "void".to_string(),
2182            };
2183            let DeferredTaskReturn::Emitted {
2184                body: mut task_return_body,
2185                name: task_return_name,
2186                params: task_return_params,
2187            } = deferred_task_return
2188            else {
2189                unreachable!()
2190            };
2191            let task_return_param_tys = task_return_params
2192                .iter()
2193                .map(|(ty, _expr)| wasm_type(*ty))
2194                .collect::<Vec<_>>()
2195                .join(", ");
2196            let task_return_param_exprs = task_return_params
2197                .iter()
2198                .map(|(_ty, expr)| expr.as_str())
2199                .collect::<Vec<_>>()
2200                .join(", ");
2201            let task_return_body = task_return_body.as_mut_string();
2202            uwriteln!(
2203                self.src.h_fns,
2204                "{snake}_callback_code_t {name}_callback({snake}_event_t *event);",
2205            );
2206            uwriteln!(self.src.h_helpers, "void {name}_return({return_ty});");
2207            let import_module = match interface_name {
2208                Some(name) => self.resolve.name_world_key(name),
2209                None => "$root".to_string(),
2210            };
2211            uwriteln!(
2212                self.src.c_helpers,
2213                r#"
2214__attribute__((__export_name__("[callback]{prefix}{export_name}")))
2215uint32_t {import_name}_callback(uint32_t event_raw, uint32_t waitable, uint32_t code) {{
2216    {snake}_event_t event;
2217    event.event = ({snake}_event_code_t) event_raw;
2218    event.waitable = waitable;
2219    event.code = code;
2220    return {name}_callback(&event);
2221}}
2222
2223__attribute__((__import_module__("[export]{import_module}"), __import_name__("{task_return_name}")))
2224void {import_name}__task_return({task_return_param_tys});
2225
2226void {name}_return({return_ty}) {{
2227    {task_return_body}
2228    {import_name}__task_return({task_return_param_exprs});
2229}}
2230                "#
2231            );
2232        } else if abi::guest_export_needs_post_return(self.resolve, func) {
2233            uwriteln!(
2234                self.src.c_fns,
2235                "__attribute__((__weak__, __export_name__(\"cabi_post_{export_name}\")))"
2236            );
2237            uwrite!(self.src.c_fns, "void {import_name}_post_return(");
2238
2239            let mut params = Vec::new();
2240            let mut c_sig = CSig {
2241                name: String::from("INVALID"),
2242                sig: String::from("INVALID"),
2243                params: Vec::new(),
2244                ret: Return::default(),
2245                retptrs: Vec::new(),
2246            };
2247            for (i, result) in sig.results.iter().enumerate() {
2248                let name = format!("arg{i}");
2249                uwrite!(self.src.c_fns, "{} {name}", wasm_type(*result));
2250                c_sig.params.push((false, name.clone()));
2251                params.push(name);
2252            }
2253            self.src.c_fns.push_str(") {\n");
2254
2255            let mut f = FunctionBindgen::new(self, c_sig, &import_name);
2256            f.params = params;
2257            abi::post_return(f.r#gen.resolve, func, &mut f);
2258            let FunctionBindgen { src, .. } = f;
2259            self.src.c_fns(&src);
2260            self.src.c_fns("}\n");
2261        }
2262
2263        self.generate_async_futures_and_streams("[export]", func, interface_name);
2264    }
2265
2266    fn print_sig(
2267        &mut self,
2268        interface_name: Option<&WorldKey>,
2269        func: &Function,
2270        sig: &WasmSignature,
2271        async_: bool,
2272    ) -> CSig {
2273        let name = self.c_func_name(interface_name, func);
2274        self.r#gen.names.insert(&name).expect("duplicate symbols");
2275
2276        let start = self.src.h_fns.len();
2277        let mut result_rets = false;
2278        let mut result_rets_has_ok_type = false;
2279
2280        let ret = if async_ && !self.in_import {
2281            Return {
2282                scalar: func.result.map(Scalar::Type),
2283                retptrs: Vec::new(),
2284            }
2285        } else {
2286            self.classify_ret(func)
2287        };
2288        if async_ {
2289            let snake = self.r#gen.world.to_snake_case();
2290            if self.in_import {
2291                uwrite!(self.src.h_fns, "{snake}_subtask_status_t");
2292            } else {
2293                uwrite!(self.src.h_fns, "{snake}_callback_code_t");
2294            }
2295        } else {
2296            match &ret.scalar {
2297                None | Some(Scalar::Void) => self.src.h_fns("void"),
2298                Some(Scalar::OptionBool(_id)) => self.src.h_fns("bool"),
2299                Some(Scalar::ResultBool(ok, _err)) => {
2300                    result_rets = true;
2301                    result_rets_has_ok_type = ok.is_some();
2302                    self.src.h_fns("bool");
2303                }
2304                Some(Scalar::Type(ty)) => self.print_ty(SourceType::HFns, ty),
2305            }
2306        }
2307        self.src.h_fns(" ");
2308        self.src.h_fns(&name);
2309        self.src.h_fns("(");
2310        let params;
2311        let mut retptrs = Vec::new();
2312        if async_ && self.in_import {
2313            params = self.print_sig_async_import_params(&name, func, sig);
2314        } else if async_ && !self.in_import {
2315            params = self.print_sig_params(func);
2316        } else {
2317            params = self.print_sig_params(func);
2318            let single_ret = ret.retptrs.len() == 1;
2319            for (i, ty) in ret.retptrs.iter().enumerate() {
2320                if i > 0 || func.params.len() > 0 {
2321                    self.src.h_fns(", ");
2322                }
2323                self.print_ty(SourceType::HFns, ty);
2324                self.src.h_fns(" *");
2325                let name: String = if result_rets {
2326                    assert!(i <= 1);
2327                    if i == 0 && result_rets_has_ok_type {
2328                        "ret".into()
2329                    } else {
2330                        "err".into()
2331                    }
2332                } else if single_ret {
2333                    "ret".into()
2334                } else {
2335                    format!("ret{}", i)
2336                };
2337                self.src.h_fns(&name);
2338                retptrs.push(name);
2339            }
2340            if func.params.len() == 0 && ret.retptrs.len() == 0 {
2341                self.src.h_fns("void");
2342            }
2343        }
2344        self.src.h_fns(")");
2345
2346        let sig = self.src.h_fns[start..].to_string();
2347        self.src.h_fns(";\n");
2348
2349        CSig {
2350            sig,
2351            name,
2352            params,
2353            ret,
2354            retptrs,
2355        }
2356    }
2357
2358    fn print_sig_params(&mut self, func: &Function) -> Vec<(bool, String)> {
2359        let mut params = Vec::new();
2360        for (i, (name, ty)) in func.params.iter().enumerate() {
2361            if i > 0 {
2362                self.src.h_fns(", ");
2363            }
2364            let pointer = is_arg_by_pointer(self.resolve, ty);
2365            // optional param pointer sig_flattening
2366            let optional_type = if let Type::Id(id) = ty {
2367                if let TypeDefKind::Option(option_ty) = &self.resolve.types[*id].kind {
2368                    if !self.r#gen.opts.no_sig_flattening {
2369                        Some(option_ty)
2370                    } else {
2371                        None
2372                    }
2373                } else {
2374                    None
2375                }
2376            } else {
2377                None
2378            };
2379            let (print_ty, print_name) = if !self.r#gen.opts.no_sig_flattening {
2380                if let Some(option_ty) = optional_type {
2381                    (option_ty, format!("maybe_{}", to_c_ident(name)))
2382                } else {
2383                    (ty, to_c_ident(name))
2384                }
2385            } else {
2386                (ty, to_c_ident(name))
2387            };
2388            self.print_ty(SourceType::HFns, print_ty);
2389            self.src.h_fns(" ");
2390            if pointer {
2391                self.src.h_fns("*");
2392            }
2393            self.src.h_fns(&print_name);
2394            params.push((optional_type.is_none() && pointer, to_c_ident(name)));
2395        }
2396        params
2397    }
2398
2399    fn print_sig_async_import_params(
2400        &mut self,
2401        c_func_name: &str,
2402        func: &Function,
2403        sig: &WasmSignature,
2404    ) -> Vec<(bool, String)> {
2405        let mut params = Vec::new();
2406        let mut printed = false;
2407        if sig.indirect_params {
2408            match &func.params[..] {
2409                [] => {}
2410                [(_name, ty)] => {
2411                    printed = true;
2412                    let name = "arg".to_string();
2413                    self.print_ty(SourceType::HFns, ty);
2414                    self.src.h_fns(" *");
2415                    self.src.h_fns(&name);
2416                    params.push((true, name));
2417                }
2418                multiple => {
2419                    printed = true;
2420                    let names = multiple
2421                        .iter()
2422                        .map(|(name, ty)| (to_c_ident(name), self.r#gen.type_name(ty)))
2423                        .collect::<Vec<_>>();
2424                    uwriteln!(self.src.h_defs, "typedef struct {c_func_name}_args {{");
2425                    for (name, ty) in names {
2426                        uwriteln!(self.src.h_defs, "{ty} {name};");
2427                    }
2428                    uwriteln!(self.src.h_defs, "}} {c_func_name}_args_t;");
2429                    uwrite!(self.src.h_fns, "{c_func_name}_args_t *args");
2430                    params.push((true, "args".to_string()));
2431                }
2432            }
2433        } else {
2434            for (name, ty) in func.params.iter() {
2435                let name = to_c_ident(name);
2436                if printed {
2437                    self.src.h_fns(", ");
2438                } else {
2439                    printed = true;
2440                }
2441                self.print_ty(SourceType::HFns, ty);
2442                self.src.h_fns(" ");
2443                self.src.h_fns(&name);
2444                params.push((false, name));
2445            }
2446        }
2447        if let Some(ty) = &func.result {
2448            if printed {
2449                self.src.h_fns(", ");
2450            } else {
2451                printed = true;
2452            }
2453            let name = "result".to_string();
2454            self.print_ty(SourceType::HFns, ty);
2455            self.src.h_fns(" *");
2456            self.src.h_fns(&name);
2457            params.push((true, name));
2458        }
2459        if !printed {
2460            self.src.h_fns("void");
2461        }
2462        params
2463    }
2464
2465    fn classify_ret(&mut self, func: &Function) -> Return {
2466        let mut ret = Return::default();
2467        match &func.result {
2468            None => ret.scalar = Some(Scalar::Void),
2469            Some(ty) => {
2470                ret.return_single(self.resolve, ty, ty, !self.r#gen.opts.no_sig_flattening);
2471            }
2472        }
2473        return ret;
2474    }
2475
2476    fn print_typedef_target(&mut self, id: TypeId) {
2477        let name = &self.r#gen.type_names[&id];
2478        self.src.h_defs(&name);
2479        self.src.h_defs(";\n");
2480    }
2481
2482    fn start_typedef_struct(&mut self, id: TypeId) {
2483        let name = &self.r#gen.type_names[&id];
2484        self.src.h_defs("typedef struct ");
2485        self.src.h_defs(&name);
2486        self.src.h_defs(" {\n");
2487    }
2488
2489    fn finish_typedef_struct(&mut self, id: TypeId) {
2490        self.src.h_defs("} ");
2491        self.print_typedef_target(id);
2492    }
2493
2494    fn owner_namespace(&self, id: TypeId) -> String {
2495        owner_namespace(
2496            self.interface,
2497            self.in_import,
2498            self.r#gen.world.clone(),
2499            self.resolve,
2500            id,
2501            &self.r#gen.renamed_interfaces,
2502        )
2503    }
2504
2505    fn print_ty(&mut self, stype: SourceType, ty: &Type) {
2506        self.r#gen
2507            .push_type_name(ty, self.src.src(stype).as_mut_string());
2508    }
2509
2510    fn docs(&mut self, docs: &Docs, stype: SourceType) {
2511        let docs = match &docs.contents {
2512            Some(docs) => docs,
2513            None => return,
2514        };
2515        let src = self.src.src(stype);
2516        for line in docs.trim().lines() {
2517            src.push_str("// ");
2518            src.push_str(line);
2519            src.push_str("\n");
2520        }
2521    }
2522
2523    fn autodrop_enabled(&self) -> bool {
2524        self.r#gen.opts.autodrop_borrows == Enabled::Yes
2525    }
2526
2527    fn contains_droppable_borrow(&self, ty: &Type) -> bool {
2528        if let Type::Id(id) = ty {
2529            match &self.resolve.types[*id].kind {
2530                TypeDefKind::Handle(h) => match h {
2531                    // Handles to imported resources will need to be dropped, if the context
2532                    // they're used in is an export.
2533                    Handle::Borrow(id) => {
2534                        !self.in_import
2535                            && matches!(
2536                                self.r#gen.resources[&dealias(self.resolve, *id)].direction,
2537                                Direction::Import
2538                            )
2539                    }
2540
2541                    Handle::Own(_) => false,
2542                },
2543
2544                TypeDefKind::Resource | TypeDefKind::Flags(_) | TypeDefKind::Enum(_) => false,
2545
2546                TypeDefKind::Record(r) => r
2547                    .fields
2548                    .iter()
2549                    .any(|f| self.contains_droppable_borrow(&f.ty)),
2550
2551                TypeDefKind::Tuple(t) => {
2552                    t.types.iter().any(|ty| self.contains_droppable_borrow(ty))
2553                }
2554
2555                TypeDefKind::Variant(v) => v.cases.iter().any(|case| {
2556                    case.ty
2557                        .as_ref()
2558                        .map_or(false, |ty| self.contains_droppable_borrow(ty))
2559                }),
2560
2561                TypeDefKind::Option(ty) => self.contains_droppable_borrow(ty),
2562
2563                TypeDefKind::Result(r) => {
2564                    r.ok.as_ref()
2565                        .map_or(false, |ty| self.contains_droppable_borrow(ty))
2566                        || r.err
2567                            .as_ref()
2568                            .map_or(false, |ty| self.contains_droppable_borrow(ty))
2569                }
2570
2571                TypeDefKind::List(ty) => self.contains_droppable_borrow(ty),
2572
2573                TypeDefKind::Future(_) | TypeDefKind::Stream(_) => false,
2574
2575                TypeDefKind::Type(ty) => self.contains_droppable_borrow(ty),
2576
2577                TypeDefKind::Unknown => false,
2578                TypeDefKind::FixedSizeList(..) => todo!(),
2579            }
2580        } else {
2581            false
2582        }
2583    }
2584
2585    fn generate_async_futures_and_streams(
2586        &mut self,
2587        prefix: &str,
2588        func: &Function,
2589        interface: Option<&WorldKey>,
2590    ) {
2591        let module = format!(
2592            "{prefix}{}",
2593            interface
2594                .map(|name| self.resolve.name_world_key(name))
2595                .unwrap_or_else(|| "$root".into())
2596        );
2597        for (index, ty) in func
2598            .find_futures_and_streams(self.resolve)
2599            .into_iter()
2600            .enumerate()
2601        {
2602            let func_name = &func.name;
2603
2604            match &self.resolve.types[ty].kind {
2605                TypeDefKind::Future(payload_type) => {
2606                    self.generate_async_future_or_stream(
2607                        PayloadFor::Future,
2608                        &module,
2609                        index,
2610                        func_name,
2611                        ty,
2612                        payload_type.as_ref(),
2613                    );
2614                }
2615                TypeDefKind::Stream(payload_type) => {
2616                    self.generate_async_future_or_stream(
2617                        PayloadFor::Stream,
2618                        &module,
2619                        index,
2620                        func_name,
2621                        ty,
2622                        payload_type.as_ref(),
2623                    );
2624                }
2625                _ => unreachable!(),
2626            }
2627        }
2628    }
2629
2630    fn generate_async_future_or_stream(
2631        &mut self,
2632        payload_for: PayloadFor,
2633        module: &str,
2634        index: usize,
2635        func_name: &str,
2636        ty: TypeId,
2637        payload_type: Option<&Type>,
2638    ) {
2639        if !self.r#gen.futures.insert(ty) {
2640            return;
2641        }
2642        let ty = self.r#gen.type_name(&Type::Id(ty));
2643        let name = ty.strip_suffix("_t").unwrap();
2644        let snake = self.r#gen.world.to_snake_case();
2645        let kind = match payload_for {
2646            PayloadFor::Future => "future",
2647            PayloadFor::Stream => "stream",
2648        };
2649        let payload_len_arg = match payload_for {
2650            PayloadFor::Future => "",
2651            PayloadFor::Stream => ", size_t",
2652        };
2653        let (read_arg_ty, read_arg_expr, write_arg_ty, write_arg_expr) =
2654            match (payload_for, payload_type) {
2655                (PayloadFor::Future, None) => ("".to_string(), "NULL", "".to_string(), "NULL"),
2656                (PayloadFor::Future, Some(ty)) => {
2657                    let ty = self.r#gen.type_name(ty);
2658                    (
2659                        format!(", {ty} *buf"),
2660                        "(uint8_t*) buf",
2661                        format!(", const {ty} *buf"),
2662                        "(const uint8_t*) buf",
2663                    )
2664                }
2665                (PayloadFor::Stream, None) => (
2666                    ", size_t amt".to_string(),
2667                    "NULL, amt",
2668                    ", size_t amt".to_string(),
2669                    "NULL, amt",
2670                ),
2671                (PayloadFor::Stream, Some(ty)) => {
2672                    let ty = self.r#gen.type_name(ty);
2673                    (
2674                        format!(", {ty} *buf, size_t amt"),
2675                        "(uint8_t*) buf, amt",
2676                        format!(", const {ty} *buf, size_t amt"),
2677                        "(const uint8_t*) buf, amt",
2678                    )
2679                }
2680            };
2681
2682        // TODO: this is a hack around space-stripping in `source.rs`, ideally
2683        // wouldn't be necessary.
2684        let empty = "";
2685        uwriteln!(
2686            self.src.h_helpers,
2687            r#"
2688typedef uint32_t {name}_writer_t;
2689
2690{ty} {name}_new({name}_writer_t *writer);
2691{snake}_waitable_status_t {name}_read({ty} reader{read_arg_ty});
2692{snake}_waitable_status_t {name}_write({name}_writer_t writer{write_arg_ty});
2693{snake}_waitable_status_t {name}_cancel_read({ty} reader);
2694{snake}_waitable_status_t {name}_cancel_write({name}_writer_t writer);
2695void {name}_drop_readable({ty} reader);{empty}
2696void {name}_drop_writable({name}_writer_t writer);
2697            "#,
2698        );
2699        uwriteln!(
2700            self.src.c_helpers,
2701            r#"
2702__attribute__((__import_module__("{module}"), __import_name__("[{kind}-new-{index}]{func_name}")))
2703extern uint64_t {name}__new(void);
2704__attribute__((__import_module__("{module}"), __import_name__("[async-lower][{kind}-read-{index}]{func_name}")))
2705extern uint32_t {name}__read(uint32_t, uint8_t*{payload_len_arg});
2706__attribute__((__import_module__("{module}"), __import_name__("[async-lower][{kind}-write-{index}]{func_name}")))
2707extern uint32_t {name}__write(uint32_t, const uint8_t*{payload_len_arg});
2708__attribute__((__import_module__("{module}"), __import_name__("[{kind}-cancel-read-{index}]{func_name}")))
2709extern uint32_t {name}__cancel_read(uint32_t);
2710__attribute__((__import_module__("{module}"), __import_name__("[{kind}-cancel-write-{index}]{func_name}")))
2711extern uint32_t {name}__cancel_write(uint32_t);
2712__attribute__((__import_module__("{module}"), __import_name__("[{kind}-drop-readable-{index}]{func_name}")))
2713extern void {name}__drop_readable(uint32_t);
2714__attribute__((__import_module__("{module}"), __import_name__("[{kind}-drop-writable-{index}]{func_name}")))
2715extern void {name}__drop_writable(uint32_t);
2716
2717{ty} {name}_new({name}_writer_t *writer) {{
2718    uint64_t packed = {name}__new();
2719    *writer = (uint32_t) (packed >> 32);
2720    return (uint32_t) packed;
2721}}
2722
2723{snake}_waitable_status_t {name}_read({ty} reader{read_arg_ty}) {{
2724    return {name}__read(reader, {read_arg_expr});
2725}}
2726
2727{snake}_waitable_status_t {name}_write({name}_writer_t writer{write_arg_ty}) {{
2728    return {name}__write(writer, {write_arg_expr});
2729}}
2730
2731{snake}_waitable_status_t {name}_cancel_read({ty} reader){empty} {{
2732    return {name}__cancel_read(reader);
2733}}
2734
2735{snake}_waitable_status_t {name}_cancel_write({name}_writer_t writer) {{
2736    return {name}__cancel_write(writer);
2737}}
2738
2739void {name}_drop_readable({ty} reader){empty} {{
2740    {name}__drop_readable(reader);
2741}}
2742
2743void {name}_drop_writable({name}_writer_t writer) {{
2744    {name}__drop_writable(writer);
2745}}
2746            "#,
2747        );
2748    }
2749}
2750
2751enum PayloadFor {
2752    Future,
2753    Stream,
2754}
2755
2756struct DroppableBorrow {
2757    name: String,
2758    ty: TypeId,
2759}
2760
2761struct FunctionBindgen<'a, 'b> {
2762    r#gen: &'a mut InterfaceGenerator<'b>,
2763    locals: Ns,
2764    src: wit_bindgen_core::Source,
2765    sig: CSig,
2766    func_to_call: &'a str,
2767    block_storage: Vec<wit_bindgen_core::Source>,
2768    blocks: Vec<(String, Vec<String>)>,
2769    payloads: Vec<String>,
2770    params: Vec<String>,
2771    wasm_return: Option<String>,
2772    ret_store_cnt: usize,
2773    import_return_pointer_area_size: ArchitectureSize,
2774    import_return_pointer_area_align: Alignment,
2775
2776    /// State of what to generate for the `task.return` intrinsic in the case
2777    /// that this bindings generator is being used for an async export.
2778    ///
2779    /// This typically stays at `DeferredTaskReturn::None` except for the case
2780    /// of async exports where they'll fill this in after the `CallInterface`
2781    /// instruction. For some more information see the documentation on
2782    /// `DeferredTaskReturn`.
2783    deferred_task_return: DeferredTaskReturn,
2784
2785    /// Borrows observed during lifting an export, that will need to be dropped when the guest
2786    /// function exits.
2787    borrows: Vec<DroppableBorrow>,
2788
2789    /// Forward declarations for temporary storage of borrow copies.
2790    borrow_decls: wit_bindgen_core::Source,
2791}
2792
2793/// State associated with the generation of the `task.return` intrinsic function
2794/// with async exports.
2795enum DeferredTaskReturn {
2796    /// Default state, meaning that either bindings generation isn't happening
2797    /// for an async export or the async export is in the bindings generation
2798    /// mode before `CallInterface`.
2799    None,
2800
2801    /// An async export is having bindings generated and `CallInterface` has
2802    /// been seen. After that instruction the `deferred_task_return` field
2803    /// transitions to this state.
2804    ///
2805    /// This state is then present until the `AsyncTaskReturn` instruction is
2806    /// met at which point this changes to `Emitted` below.
2807    Generating {
2808        /// The previous contents of `self.src` just after the `CallInterface`
2809        /// had its code generator. This is effectively the bindings-generated
2810        /// contents of the export and this will get replaced back into
2811        /// `self.src` once the `AsyncTaskReturn` is generated.
2812        prev_src: wit_bindgen_core::Source,
2813    },
2814
2815    /// An `AsyncTaskReturn` has been seen and all state is now located here to
2816    /// be used for generating the `task.return` intrinsic.
2817    ///
2818    /// This state is only generated during `AsyncTaskReturn` and is used to
2819    /// record everything necessary to generate `task.return` meaning that the
2820    /// in-`FunctionBindgen` state is now "back to normal" where it's intended
2821    /// for the main function having bindings generated.
2822    Emitted {
2823        /// The name of the `task.return` intrinsic that should be imported.
2824        /// Note that this does not include the module.
2825        name: String,
2826        /// The wasm type of each parameter provided to the `task.return`
2827        /// intrinsic as well as the C expression necessary to produce this
2828        /// parameter. The type is used to declare the intrinsic and the C
2829        /// expression is used to call the intrinsic from the generated
2830        /// function.
2831        params: Vec<(WasmType, String)>,
2832        /// The body of the `task.return` intrinsic. This contains the bulk of
2833        /// the lowering code from a function's return value to the canonical
2834        /// ABI.
2835        body: wit_bindgen_core::Source,
2836    },
2837}
2838
2839impl<'a, 'b> FunctionBindgen<'a, 'b> {
2840    fn new(
2841        r#gen: &'a mut InterfaceGenerator<'b>,
2842        sig: CSig,
2843        func_to_call: &'a str,
2844    ) -> FunctionBindgen<'a, 'b> {
2845        let mut locals = Ns::default();
2846        for (_, name) in sig.params.iter() {
2847            locals.insert(name).unwrap();
2848        }
2849        FunctionBindgen {
2850            r#gen,
2851            sig,
2852            locals,
2853            src: Default::default(),
2854            func_to_call,
2855            block_storage: Vec::new(),
2856            blocks: Vec::new(),
2857            payloads: Vec::new(),
2858            params: Vec::new(),
2859            wasm_return: None,
2860            ret_store_cnt: 0,
2861            import_return_pointer_area_size: Default::default(),
2862            import_return_pointer_area_align: Default::default(),
2863            borrow_decls: Default::default(),
2864            borrows: Vec::new(),
2865            deferred_task_return: DeferredTaskReturn::None,
2866        }
2867    }
2868
2869    fn store_op(&mut self, op: &str, loc: &str) {
2870        self.src.push_str(loc);
2871        self.src.push_str(" = ");
2872        self.src.push_str(op);
2873        self.src.push_str(";\n");
2874    }
2875
2876    fn load(
2877        &mut self,
2878        ty: &str,
2879        offset: ArchitectureSize,
2880        operands: &[String],
2881        results: &mut Vec<String>,
2882    ) {
2883        results.push(format!(
2884            "*(({}*) ({} + {}))",
2885            ty,
2886            operands[0],
2887            offset.format(POINTER_SIZE_EXPRESSION)
2888        ));
2889    }
2890
2891    fn load_ext(
2892        &mut self,
2893        ty: &str,
2894        offset: ArchitectureSize,
2895        operands: &[String],
2896        results: &mut Vec<String>,
2897    ) {
2898        self.load(ty, offset, operands, results);
2899        let result = results.pop().unwrap();
2900        results.push(format!("(int32_t) {}", result));
2901    }
2902
2903    fn store(&mut self, ty: &str, offset: ArchitectureSize, operands: &[String]) {
2904        uwriteln!(
2905            self.src,
2906            "*(({}*)({} + {})) = {};",
2907            ty,
2908            operands[1],
2909            offset.format(POINTER_SIZE_EXPRESSION),
2910            operands[0]
2911        );
2912    }
2913
2914    fn store_in_retptr(&mut self, operand: &String) {
2915        self.store_op(
2916            operand,
2917            &format!("*{}", self.sig.retptrs[self.ret_store_cnt]),
2918        );
2919        self.ret_store_cnt = self.ret_store_cnt + 1;
2920    }
2921
2922    fn empty_return_value(&mut self) {
2923        // Empty types have no state, so we don't emit stores for them. But we
2924        // do need to keep track of which return variable we're looking at.
2925        self.ret_store_cnt = self.ret_store_cnt + 1;
2926    }
2927
2928    fn assert_no_droppable_borrows(&self, context: &str, ty: &Type) {
2929        if !self.r#gen.in_import
2930            && self.r#gen.autodrop_enabled()
2931            && self.r#gen.contains_droppable_borrow(ty)
2932        {
2933            panic!(
2934                "Unable to autodrop borrows in `{}` values, please disable autodrop",
2935                context
2936            )
2937        }
2938    }
2939}
2940
2941impl Bindgen for FunctionBindgen<'_, '_> {
2942    type Operand = String;
2943
2944    fn sizes(&self) -> &SizeAlign {
2945        &self.r#gen.r#gen.sizes
2946    }
2947
2948    fn push_block(&mut self) {
2949        let prev = mem::take(&mut self.src);
2950        self.block_storage.push(prev);
2951    }
2952
2953    fn finish_block(&mut self, operands: &mut Vec<String>) {
2954        let to_restore = self.block_storage.pop().unwrap();
2955        let src = mem::replace(&mut self.src, to_restore);
2956        self.blocks.push((src.into(), mem::take(operands)));
2957    }
2958
2959    fn return_pointer(&mut self, size: ArchitectureSize, align: Alignment) -> String {
2960        let ptr = self.locals.tmp("ptr");
2961
2962        // Use a stack-based return area for imports, because exports need
2963        // their return area to be live until the post-return call.
2964        if self.r#gen.in_import {
2965            self.import_return_pointer_area_size = self.import_return_pointer_area_size.max(size);
2966            self.import_return_pointer_area_align =
2967                self.import_return_pointer_area_align.max(align);
2968            uwriteln!(self.src, "uint8_t *{} = (uint8_t *) &ret_area;", ptr);
2969        } else {
2970            self.r#gen.r#gen.return_pointer_area_size =
2971                self.r#gen.r#gen.return_pointer_area_size.max(size);
2972            self.r#gen.r#gen.return_pointer_area_align =
2973                self.r#gen.r#gen.return_pointer_area_align.max(align);
2974            // Declare a statically-allocated return area.
2975            uwriteln!(self.src, "uint8_t *{} = (uint8_t *) &RET_AREA;", ptr);
2976        }
2977
2978        ptr
2979    }
2980
2981    fn is_list_canonical(&self, resolve: &Resolve, ty: &Type) -> bool {
2982        resolve.all_bits_valid(ty)
2983    }
2984
2985    fn emit(
2986        &mut self,
2987        resolve: &Resolve,
2988        inst: &Instruction<'_>,
2989        operands: &mut Vec<String>,
2990        results: &mut Vec<String>,
2991    ) {
2992        match inst {
2993            Instruction::GetArg { nth } => results.push(self.params[*nth].clone()),
2994            Instruction::I32Const { val } => results.push(val.to_string()),
2995            Instruction::ConstZero { tys } => {
2996                for _ in tys.iter() {
2997                    results.push("0".to_string());
2998                }
2999            }
3000
3001            // TODO: checked?
3002            Instruction::U8FromI32 => results.push(format!("(uint8_t) ({})", operands[0])),
3003            Instruction::S8FromI32 => results.push(format!("(int8_t) ({})", operands[0])),
3004            Instruction::U16FromI32 => results.push(format!("(uint16_t) ({})", operands[0])),
3005            Instruction::S16FromI32 => results.push(format!("(int16_t) ({})", operands[0])),
3006            Instruction::U32FromI32 => results.push(format!("(uint32_t) ({})", operands[0])),
3007            Instruction::S32FromI32 | Instruction::S64FromI64 => results.push(operands[0].clone()),
3008            Instruction::U64FromI64 => results.push(format!("(uint64_t) ({})", operands[0])),
3009
3010            Instruction::I32FromU8
3011            | Instruction::I32FromS8
3012            | Instruction::I32FromU16
3013            | Instruction::I32FromS16
3014            | Instruction::I32FromU32 => {
3015                results.push(format!("(int32_t) ({})", operands[0]));
3016            }
3017            Instruction::I32FromS32 | Instruction::I64FromS64 => results.push(operands[0].clone()),
3018            Instruction::I64FromU64 => {
3019                results.push(format!("(int64_t) ({})", operands[0]));
3020            }
3021
3022            // f32/f64 have the same representation in the import type and in C,
3023            // so no conversions necessary.
3024            Instruction::CoreF32FromF32
3025            | Instruction::CoreF64FromF64
3026            | Instruction::F32FromCoreF32
3027            | Instruction::F64FromCoreF64 => {
3028                results.push(operands[0].clone());
3029            }
3030
3031            // TODO: checked
3032            Instruction::CharFromI32 => {
3033                results.push(format!("(uint32_t) ({})", operands[0]));
3034            }
3035            Instruction::I32FromChar => {
3036                results.push(format!("(int32_t) ({})", operands[0]));
3037            }
3038
3039            Instruction::Bitcasts { casts } => {
3040                for (cast, op) in casts.iter().zip(operands) {
3041                    let op = self.r#gen.r#gen.perform_cast(op, cast);
3042                    results.push(op);
3043                }
3044            }
3045
3046            Instruction::BoolFromI32 | Instruction::I32FromBool => {
3047                results.push(operands[0].clone());
3048            }
3049
3050            Instruction::RecordLower { record, .. } => {
3051                let op = &operands[0];
3052                for f in record.fields.iter() {
3053                    results.push(format!("({}).{}", op, to_c_ident(&f.name)));
3054                }
3055            }
3056            Instruction::RecordLift { ty, record, .. } => {
3057                let name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3058                let mut result = format!("({}) {{\n", name);
3059                for (field, op) in record.fields.iter().zip(operands.iter()) {
3060                    let field_ty = self.r#gen.r#gen.type_name(&field.ty);
3061                    uwriteln!(result, "({}) {},", field_ty, op);
3062                }
3063                result.push_str("}");
3064                results.push(result);
3065            }
3066
3067            Instruction::TupleLower { tuple, .. } => {
3068                let op = &operands[0];
3069                for i in 0..tuple.types.len() {
3070                    results.push(format!("({}).f{}", op, i));
3071                }
3072            }
3073            Instruction::TupleLift { ty, tuple, .. } => {
3074                let name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3075                let mut result = format!("({}) {{\n", name);
3076                for (ty, op) in tuple.types.iter().zip(operands.iter()) {
3077                    let ty = self.r#gen.r#gen.type_name(&ty);
3078                    uwriteln!(result, "({}) {},", ty, op);
3079                }
3080                result.push_str("}");
3081                results.push(result);
3082            }
3083
3084            Instruction::HandleLower { .. } => {
3085                let op = &operands[0];
3086                results.push(format!("({op}).__handle"))
3087            }
3088
3089            Instruction::HandleLift { handle, ty, .. } => match handle {
3090                Handle::Borrow(resource)
3091                    if matches!(
3092                        self.r#gen.r#gen.resources[&dealias(resolve, *resource)].direction,
3093                        Direction::Export
3094                    ) =>
3095                {
3096                    // Here we've received a borrow of a resource which we've exported ourselves, so we can treat
3097                    // it as a raw pointer rather than an opaque handle.
3098                    let op = &operands[0];
3099                    let name = self
3100                        .r#gen
3101                        .r#gen
3102                        .type_name(&Type::Id(dealias(resolve, *resource)));
3103                    results.push(format!("(({name}*) {op})"))
3104                }
3105                _ => {
3106                    let op = &operands[0];
3107                    let name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3108                    results.push(format!("({name}) {{ {op} }}"));
3109
3110                    if let Handle::Borrow(id) = handle {
3111                        if !self.r#gen.in_import && self.r#gen.autodrop_enabled() {
3112                            // Here we've received a borrow of an imported resource, which is the
3113                            // kind we'll need to drop when the exported function is returning.
3114                            let ty = dealias(self.r#gen.resolve, *id);
3115
3116                            let name = self.locals.tmp("borrow");
3117                            uwriteln!(self.borrow_decls, "int32_t {name} = 0;");
3118                            uwriteln!(self.src, "{name} = {op};");
3119
3120                            self.borrows.push(DroppableBorrow { name, ty });
3121                        }
3122                    }
3123                }
3124            },
3125
3126            // TODO: checked
3127            Instruction::FlagsLower { flags, ty, .. } => match flags_repr(flags) {
3128                Int::U8 | Int::U16 | Int::U32 => {
3129                    results.push(operands.pop().unwrap());
3130                }
3131                Int::U64 => {
3132                    let name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3133                    let tmp = self.locals.tmp("flags");
3134                    uwriteln!(self.src, "{name} {tmp} = {};", operands[0]);
3135                    results.push(format!("{tmp} & 0xffffffff"));
3136                    results.push(format!("({tmp} >> 32) & 0xffffffff"));
3137                }
3138            },
3139
3140            Instruction::FlagsLift { flags, ty, .. } => match flags_repr(flags) {
3141                Int::U8 | Int::U16 | Int::U32 => {
3142                    results.push(operands.pop().unwrap());
3143                }
3144                Int::U64 => {
3145                    let name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3146                    let op0 = &operands[0];
3147                    let op1 = &operands[1];
3148                    results.push(format!("(({name}) ({op0})) | ((({name}) ({op1})) << 32)"));
3149                }
3150            },
3151
3152            Instruction::VariantPayloadName => {
3153                let name = self.locals.tmp("payload");
3154                results.push(format!("*{}", name));
3155                self.payloads.push(name);
3156            }
3157
3158            Instruction::VariantLower {
3159                variant,
3160                results: result_types,
3161                ..
3162            } => {
3163                let blocks = self
3164                    .blocks
3165                    .drain(self.blocks.len() - variant.cases.len()..)
3166                    .collect::<Vec<_>>();
3167                let payloads = self
3168                    .payloads
3169                    .drain(self.payloads.len() - variant.cases.len()..)
3170                    .collect::<Vec<_>>();
3171
3172                let mut variant_results = Vec::with_capacity(result_types.len());
3173                for ty in result_types.iter() {
3174                    let name = self.locals.tmp("variant");
3175                    results.push(name.clone());
3176                    self.src.push_str(wasm_type(*ty));
3177                    self.src.push_str(" ");
3178                    self.src.push_str(&name);
3179                    self.src.push_str(";\n");
3180                    variant_results.push(name);
3181                }
3182
3183                let expr_to_match = format!("({}).tag", operands[0]);
3184
3185                uwriteln!(self.src, "switch ((int32_t) {}) {{", expr_to_match);
3186                for (i, ((case, (block, block_results)), payload)) in
3187                    variant.cases.iter().zip(blocks).zip(payloads).enumerate()
3188                {
3189                    uwriteln!(self.src, "case {}: {{", i);
3190                    if let Some(ty) = case.ty.as_ref() {
3191                        let ty = self.r#gen.r#gen.type_name(ty);
3192                        uwrite!(
3193                            self.src,
3194                            "const {} *{} = &({}).val",
3195                            ty,
3196                            payload,
3197                            operands[0],
3198                        );
3199                        self.src.push_str(".");
3200                        self.src.push_str(&to_c_ident(&case.name));
3201                        self.src.push_str(";\n");
3202                    }
3203                    self.src.push_str(&block);
3204
3205                    for (name, result) in variant_results.iter().zip(&block_results) {
3206                        uwriteln!(self.src, "{} = {};", name, result);
3207                    }
3208                    self.src.push_str("break;\n}\n");
3209                }
3210                self.src.push_str("}\n");
3211            }
3212
3213            Instruction::VariantLift { variant, ty, .. } => {
3214                let blocks = self
3215                    .blocks
3216                    .drain(self.blocks.len() - variant.cases.len()..)
3217                    .collect::<Vec<_>>();
3218
3219                let ty = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3220                let result = self.locals.tmp("variant");
3221                uwriteln!(self.src, "{} {};", ty, result);
3222                uwriteln!(self.src, "{}.tag = {};", result, operands[0]);
3223                uwriteln!(self.src, "switch ((int32_t) {}.tag) {{", result);
3224                for (i, (case, (block, block_results))) in
3225                    variant.cases.iter().zip(blocks).enumerate()
3226                {
3227                    uwriteln!(self.src, "case {}: {{", i);
3228                    self.src.push_str(&block);
3229                    assert!(block_results.len() == (case.ty.is_some() as usize));
3230
3231                    if let Some(_) = case.ty.as_ref() {
3232                        let mut dst = format!("{}.val", result);
3233                        dst.push_str(".");
3234                        dst.push_str(&to_c_ident(&case.name));
3235                        self.store_op(&block_results[0], &dst);
3236                    }
3237                    self.src.push_str("break;\n}\n");
3238                }
3239                self.src.push_str("}\n");
3240                results.push(result);
3241            }
3242
3243            Instruction::OptionLower {
3244                results: result_types,
3245                payload,
3246                ..
3247            } => {
3248                let (mut some, some_results) = self.blocks.pop().unwrap();
3249                let (mut none, none_results) = self.blocks.pop().unwrap();
3250                let some_payload = self.payloads.pop().unwrap();
3251                let _none_payload = self.payloads.pop().unwrap();
3252
3253                for (i, ty) in result_types.iter().enumerate() {
3254                    let name = self.locals.tmp("option");
3255                    results.push(name.clone());
3256                    self.src.push_str(wasm_type(*ty));
3257                    self.src.push_str(" ");
3258                    self.src.push_str(&name);
3259                    self.src.push_str(";\n");
3260                    let some_result = &some_results[i];
3261                    uwriteln!(some, "{name} = {some_result};");
3262                    let none_result = &none_results[i];
3263                    uwriteln!(none, "{name} = {none_result};");
3264                }
3265
3266                let op0 = &operands[0];
3267                let ty = self.r#gen.r#gen.type_name(payload);
3268                let bind_some = format!("const {ty} *{some_payload} = &({op0}).val;");
3269
3270                uwrite!(
3271                    self.src,
3272                    "\
3273                    if (({op0}).is_some) {{
3274                        {bind_some}
3275                        {some}}} else {{
3276                        {none}}}
3277                    "
3278                );
3279            }
3280
3281            Instruction::OptionLift { ty, .. } => {
3282                let (mut some, some_results) = self.blocks.pop().unwrap();
3283                let (mut none, none_results) = self.blocks.pop().unwrap();
3284                assert!(none_results.len() == 0);
3285                assert!(some_results.len() == 1);
3286                let some_result = &some_results[0];
3287
3288                let ty = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3289                let result = self.locals.tmp("option");
3290                uwriteln!(self.src, "{ty} {result};");
3291                let op0 = &operands[0];
3292                let set_some = format!("{result}.val = {some_result};\n");
3293                if none.len() > 0 {
3294                    none.push('\n');
3295                }
3296                if some.len() > 0 {
3297                    some.push('\n');
3298                }
3299                uwrite!(
3300                    self.src,
3301                    "switch ({op0}) {{
3302                        case 0: {{
3303                            {result}.is_some = false;
3304                            {none}\
3305                            break;
3306                        }}
3307                        case 1: {{
3308                            {result}.is_some = true;
3309                            {some}\
3310                            {set_some}\
3311                            break;
3312                        }}
3313                    }}\n"
3314                );
3315                results.push(result);
3316            }
3317
3318            Instruction::ResultLower {
3319                results: result_types,
3320                result,
3321                ..
3322            } => {
3323                let (mut err, err_results) = self.blocks.pop().unwrap();
3324                let (mut ok, ok_results) = self.blocks.pop().unwrap();
3325                let err_payload = self.payloads.pop().unwrap();
3326                let ok_payload = self.payloads.pop().unwrap();
3327
3328                for (i, ty) in result_types.iter().enumerate() {
3329                    let name = self.locals.tmp("result");
3330                    results.push(name.clone());
3331                    self.src.push_str(wasm_type(*ty));
3332                    self.src.push_str(" ");
3333                    self.src.push_str(&name);
3334                    self.src.push_str(";\n");
3335                    let ok_result = &ok_results[i];
3336                    uwriteln!(ok, "{name} = {ok_result};");
3337                    let err_result = &err_results[i];
3338                    uwriteln!(err, "{name} = {err_result};");
3339                }
3340
3341                let op0 = &operands[0];
3342                let bind_ok = if let Some(ok) = result.ok.as_ref() {
3343                    let ok_ty = self.r#gen.r#gen.type_name(ok);
3344                    format!("const {ok_ty} *{ok_payload} = &({op0}).val.ok;")
3345                } else {
3346                    String::new()
3347                };
3348                let bind_err = if let Some(err) = result.err.as_ref() {
3349                    let err_ty = self.r#gen.r#gen.type_name(err);
3350                    format!("const {err_ty} *{err_payload} = &({op0}).val.err;")
3351                } else {
3352                    String::new()
3353                };
3354                uwrite!(
3355                    self.src,
3356                    "\
3357                    if (({op0}).is_err) {{
3358                        {bind_err}\
3359                        {err}\
3360                    }} else {{
3361                        {bind_ok}\
3362                        {ok}\
3363                    }}
3364                    "
3365                );
3366            }
3367
3368            Instruction::ResultLift { result, ty, .. } => {
3369                let (mut err, err_results) = self.blocks.pop().unwrap();
3370                assert!(err_results.len() == (result.err.is_some() as usize));
3371                let (mut ok, ok_results) = self.blocks.pop().unwrap();
3372                assert!(ok_results.len() == (result.ok.is_some() as usize));
3373
3374                if err.len() > 0 {
3375                    err.push_str("\n");
3376                }
3377                if ok.len() > 0 {
3378                    ok.push_str("\n");
3379                }
3380
3381                let result_tmp = self.locals.tmp("result");
3382                let set_ok = if let Some(_) = result.ok.as_ref() {
3383                    let ok_result = &ok_results[0];
3384                    format!("{result_tmp}.val.ok = {ok_result};\n")
3385                } else {
3386                    String::new()
3387                };
3388                let set_err = if let Some(_) = result.err.as_ref() {
3389                    let err_result = &err_results[0];
3390                    format!("{result_tmp}.val.err = {err_result};\n")
3391                } else {
3392                    String::new()
3393                };
3394
3395                let ty = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3396                uwriteln!(self.src, "{ty} {result_tmp};");
3397                let op0 = &operands[0];
3398                uwriteln!(
3399                    self.src,
3400                    "switch ({op0}) {{
3401                        case 0: {{
3402                            {result_tmp}.is_err = false;
3403                            {ok}\
3404                            {set_ok}\
3405                            break;
3406                        }}
3407                        case 1: {{
3408                            {result_tmp}.is_err = true;
3409                            {err}\
3410                            {set_err}\
3411                            break;
3412                        }}
3413                    }}"
3414                );
3415                results.push(result_tmp);
3416            }
3417
3418            Instruction::EnumLower { .. } => results.push(format!("(int32_t) {}", operands[0])),
3419            Instruction::EnumLift { .. } => results.push(operands.pop().unwrap()),
3420
3421            Instruction::ListCanonLower { .. } | Instruction::StringLower { .. } => {
3422                results.push(format!("(uint8_t *) ({}).ptr", operands[0]));
3423                results.push(format!("({}).len", operands[0]));
3424            }
3425            Instruction::ListCanonLift { element, ty, .. } => {
3426                self.assert_no_droppable_borrows("list", &Type::Id(*ty));
3427
3428                let list_name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3429                let elem_name = self.r#gen.r#gen.type_name(element);
3430                results.push(format!(
3431                    "({}) {{ ({}*)({}), ({}) }}",
3432                    list_name, elem_name, operands[0], operands[1]
3433                ));
3434            }
3435            Instruction::StringLift { .. } => {
3436                let list_name = self.r#gen.r#gen.type_name(&Type::String);
3437                results.push(format!(
3438                    "({}) {{ ({}*)({}), ({}) }}",
3439                    list_name,
3440                    self.r#gen.r#gen.char_type(),
3441                    operands[0],
3442                    operands[1]
3443                ));
3444            }
3445
3446            Instruction::ListLower { .. } => {
3447                let _body = self.blocks.pop().unwrap();
3448                results.push(format!("(uint8_t *) ({}).ptr", operands[0]));
3449                results.push(format!("({}).len", operands[0]));
3450            }
3451
3452            Instruction::ListLift { element, ty, .. } => {
3453                self.assert_no_droppable_borrows("list", &Type::Id(*ty));
3454
3455                let _body = self.blocks.pop().unwrap();
3456                let list_name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3457                let elem_name = self.r#gen.r#gen.type_name(element);
3458                results.push(format!(
3459                    "({}) {{ ({}*)({}), ({}) }}",
3460                    list_name, elem_name, operands[0], operands[1]
3461                ));
3462            }
3463            Instruction::IterElem { .. } => results.push("e".to_string()),
3464            Instruction::IterBasePointer => results.push("base".to_string()),
3465
3466            Instruction::CallWasm { sig, .. } => {
3467                match sig.results.len() {
3468                    0 => {}
3469                    1 => {
3470                        self.src.push_str(wasm_type(sig.results[0]));
3471                        let ret = self.locals.tmp("ret");
3472                        self.wasm_return = Some(ret.clone());
3473                        uwrite!(self.src, " {} = ", ret);
3474                        results.push(ret);
3475                    }
3476                    _ => unimplemented!(),
3477                }
3478                self.src.push_str(self.func_to_call);
3479                self.src.push_str("(");
3480                for (i, op) in operands.iter().enumerate() {
3481                    if i > 0 {
3482                        self.src.push_str(", ");
3483                    }
3484                    self.src.push_str(op);
3485                }
3486                self.src.push_str(");\n");
3487            }
3488
3489            Instruction::CallInterface { func, async_ } => {
3490                let mut args = String::new();
3491                for (i, (op, (byref, _))) in operands.iter().zip(&self.sig.params).enumerate() {
3492                    if i > 0 {
3493                        args.push_str(", ");
3494                    }
3495                    let ty = &func.params[i].1;
3496                    if *byref {
3497                        let name = self.locals.tmp("arg");
3498                        let ty = self.r#gen.r#gen.type_name(ty);
3499                        uwriteln!(self.src, "{} {} = {};", ty, name, op);
3500                        args.push_str("&");
3501                        args.push_str(&name);
3502                    } else {
3503                        if !self.r#gen.in_import {
3504                            if let Type::Id(id) = ty {
3505                                if let TypeDefKind::Option(_) = &self.r#gen.resolve.types[*id].kind
3506                                {
3507                                    uwrite!(args, "{op}.is_some ? &({op}.val) : NULL");
3508                                    continue;
3509                                }
3510                            }
3511                        }
3512                        args.push_str(op);
3513                    }
3514                }
3515                if *async_ {
3516                    let ret = self.locals.tmp("ret");
3517                    let snake = self.r#gen.r#gen.world.to_snake_case();
3518                    uwriteln!(
3519                        self.src,
3520                        "{snake}_callback_code_t {ret} = {}({args});",
3521                        self.sig.name,
3522                    );
3523                    uwriteln!(self.src, "return {ret};");
3524                    if func.result.is_some() {
3525                        results.push("ret".to_string());
3526                    }
3527                    assert!(matches!(
3528                        self.deferred_task_return,
3529                        DeferredTaskReturn::None
3530                    ));
3531                    self.deferred_task_return = DeferredTaskReturn::Generating {
3532                        prev_src: mem::take(&mut self.src),
3533                    };
3534                    return;
3535                }
3536                match &self.sig.ret.scalar {
3537                    None => {
3538                        let mut retptrs = Vec::new();
3539                        for ty in self.sig.ret.retptrs.iter() {
3540                            let name = self.locals.tmp("ret");
3541                            let ty = self.r#gen.r#gen.type_name(ty);
3542                            uwriteln!(self.src, "{} {};", ty, name);
3543                            if args.len() > 0 {
3544                                args.push_str(", ");
3545                            }
3546                            args.push_str("&");
3547                            args.push_str(&name);
3548                            retptrs.push(name);
3549                        }
3550                        uwriteln!(self.src, "{}({});", self.sig.name, args);
3551                        results.extend(retptrs);
3552                    }
3553                    Some(Scalar::Void) => {
3554                        uwriteln!(self.src, "{}({});", self.sig.name, args);
3555                    }
3556                    Some(Scalar::Type(_)) => {
3557                        let ret = self.locals.tmp("ret");
3558                        let ty = func.result.unwrap();
3559                        let ty = self.r#gen.r#gen.type_name(&ty);
3560                        uwriteln!(self.src, "{} {} = {}({});", ty, ret, self.sig.name, args);
3561                        results.push(ret);
3562                    }
3563                    Some(Scalar::OptionBool(ty)) => {
3564                        let ret = self.locals.tmp("ret");
3565                        let val = self.locals.tmp("val");
3566                        if args.len() > 0 {
3567                            args.push_str(", ");
3568                        }
3569                        args.push_str("&");
3570                        args.push_str(&val);
3571                        let payload_ty = self.r#gen.r#gen.type_name(ty);
3572                        uwriteln!(self.src, "{} {};", payload_ty, val);
3573                        uwriteln!(self.src, "bool {} = {}({});", ret, self.sig.name, args);
3574                        let ty = func.result.unwrap();
3575                        let option_ty = self.r#gen.r#gen.type_name(&ty);
3576                        let option_ret = self.locals.tmp("ret");
3577                        uwrite!(
3578                            self.src,
3579                            "
3580                                {option_ty} {option_ret};
3581                                {option_ret}.is_some = {ret};
3582                                {option_ret}.val = {val};
3583                            ",
3584                        );
3585                        results.push(option_ret);
3586                    }
3587                    Some(Scalar::ResultBool(ok, err)) => {
3588                        let ty = &func.result.unwrap();
3589                        let result_ty = self.r#gen.r#gen.type_name(ty);
3590                        let ret = self.locals.tmp("ret");
3591                        let mut ret_iter = self.sig.ret.retptrs.iter();
3592                        uwriteln!(self.src, "{result_ty} {ret};");
3593                        let ok_name = if ok.is_some() {
3594                            if let Some(ty) = ret_iter.next() {
3595                                let val = self.locals.tmp("ok");
3596                                if args.len() > 0 {
3597                                    uwrite!(args, ", ");
3598                                }
3599                                uwrite!(args, "&{val}");
3600                                let ty = self.r#gen.r#gen.type_name(ty);
3601                                uwriteln!(self.src, "{} {};", ty, val);
3602                                Some(val)
3603                            } else {
3604                                None
3605                            }
3606                        } else {
3607                            None
3608                        };
3609                        let err_name = if let Some(ty) = ret_iter.next() {
3610                            let val = self.locals.tmp("err");
3611                            if args.len() > 0 {
3612                                uwrite!(args, ", ")
3613                            }
3614                            uwrite!(args, "&{val}");
3615                            let ty = self.r#gen.r#gen.type_name(ty);
3616                            uwriteln!(self.src, "{} {};", ty, val);
3617                            Some(val)
3618                        } else {
3619                            None
3620                        };
3621                        assert!(ret_iter.next().is_none());
3622                        uwrite!(self.src, "");
3623                        uwriteln!(self.src, "{ret}.is_err = !{}({args});", self.sig.name);
3624                        if err.is_some() {
3625                            if let Some(err_name) = err_name {
3626                                uwriteln!(
3627                                    self.src,
3628                                    "if ({ret}.is_err) {{
3629                                        {ret}.val.err = {err_name};
3630                                    }}",
3631                                );
3632                            }
3633                        }
3634                        if ok.is_some() {
3635                            if let Some(ok_name) = ok_name {
3636                                uwriteln!(
3637                                    self.src,
3638                                    "if (!{ret}.is_err) {{
3639                                        {ret}.val.ok = {ok_name};
3640                                    }}"
3641                                );
3642                            } else {
3643                                uwrite!(self.src, "\n");
3644                            }
3645                        }
3646                        results.push(ret);
3647                    }
3648                }
3649            }
3650            Instruction::Return { .. } if self.r#gen.in_import => match self.sig.ret.scalar {
3651                None => {
3652                    for op in operands.iter() {
3653                        self.store_in_retptr(op);
3654                    }
3655                }
3656                Some(Scalar::Void) => {
3657                    assert!(operands.is_empty());
3658                }
3659                Some(Scalar::Type(_)) => {
3660                    assert_eq!(operands.len(), 1);
3661                    self.src.push_str("return ");
3662                    self.src.push_str(&operands[0]);
3663                    self.src.push_str(";\n");
3664                }
3665                Some(Scalar::OptionBool(_)) => {
3666                    assert_eq!(operands.len(), 1);
3667                    let variant = &operands[0];
3668                    self.store_in_retptr(&format!("{}.val", variant));
3669                    self.src.push_str("return ");
3670                    self.src.push_str(&variant);
3671                    self.src.push_str(".is_some;\n");
3672                }
3673                Some(Scalar::ResultBool(ok, err)) => {
3674                    assert_eq!(operands.len(), 1);
3675                    let variant = &operands[0];
3676                    assert!(self.sig.retptrs.len() <= 2);
3677                    uwriteln!(self.src, "if (!{}.is_err) {{", variant);
3678                    if ok.is_some() {
3679                        if ok.is_some() {
3680                            self.store_in_retptr(&format!("{}.val.ok", variant));
3681                        } else {
3682                            self.empty_return_value();
3683                        }
3684                    }
3685                    uwriteln!(
3686                        self.src,
3687                        "   return 1;
3688                            }} else {{"
3689                    );
3690                    if err.is_some() {
3691                        if err.is_some() {
3692                            self.store_in_retptr(&format!("{}.val.err", variant));
3693                        } else {
3694                            self.empty_return_value();
3695                        }
3696                    }
3697                    uwriteln!(
3698                        self.src,
3699                        "   return 0;
3700                            }}"
3701                    );
3702                    assert_eq!(self.ret_store_cnt, self.sig.retptrs.len());
3703                }
3704            },
3705            Instruction::Return { amt, .. } => {
3706                // Emit all temporary borrow decls
3707                let src = std::mem::replace(&mut self.src, std::mem::take(&mut self.borrow_decls));
3708                self.src.append_src(&src);
3709
3710                for DroppableBorrow { name, ty } in self.borrows.iter() {
3711                    let drop_fn = self.r#gen.r#gen.resources[ty].drop_fn.as_str();
3712                    uwriteln!(self.src, "if ({name} != 0) {{");
3713                    uwriteln!(self.src, "  {drop_fn}({name});");
3714                    uwriteln!(self.src, "}}");
3715                }
3716
3717                assert!(*amt <= 1);
3718                if *amt == 1 {
3719                    uwriteln!(self.src, "return {};", operands[0]);
3720                }
3721            }
3722
3723            Instruction::I32Load { offset } => self.load("int32_t", *offset, operands, results),
3724            Instruction::I64Load { offset } => self.load("int64_t", *offset, operands, results),
3725            Instruction::F32Load { offset } => self.load("float", *offset, operands, results),
3726            Instruction::F64Load { offset } => self.load("double", *offset, operands, results),
3727            Instruction::PointerLoad { offset } => {
3728                self.load("uint8_t *", *offset, operands, results)
3729            }
3730            Instruction::LengthLoad { offset } => self.load("size_t", *offset, operands, results),
3731            Instruction::I32Store { offset } => self.store("int32_t", *offset, operands),
3732            Instruction::I64Store { offset } => self.store("int64_t", *offset, operands),
3733            Instruction::F32Store { offset } => self.store("float", *offset, operands),
3734            Instruction::F64Store { offset } => self.store("double", *offset, operands),
3735            Instruction::I32Store8 { offset } => self.store("int8_t", *offset, operands),
3736            Instruction::I32Store16 { offset } => self.store("int16_t", *offset, operands),
3737            Instruction::PointerStore { offset } => self.store("uint8_t *", *offset, operands),
3738            Instruction::LengthStore { offset } => self.store("size_t", *offset, operands),
3739
3740            Instruction::I32Load8U { offset } => {
3741                self.load_ext("uint8_t", *offset, operands, results)
3742            }
3743            Instruction::I32Load8S { offset } => {
3744                self.load_ext("int8_t", *offset, operands, results)
3745            }
3746            Instruction::I32Load16U { offset } => {
3747                self.load_ext("uint16_t", *offset, operands, results)
3748            }
3749            Instruction::I32Load16S { offset } => {
3750                self.load_ext("int16_t", *offset, operands, results)
3751            }
3752
3753            Instruction::GuestDeallocate { .. } => {
3754                uwriteln!(self.src, "free({});", operands[0]);
3755            }
3756            Instruction::GuestDeallocateString => {
3757                uwriteln!(self.src, "if (({}) > 0) {{", operands[1]);
3758                uwriteln!(self.src, "free({});", operands[0]);
3759                uwriteln!(self.src, "}}");
3760            }
3761            Instruction::GuestDeallocateVariant { blocks } => {
3762                let blocks = self
3763                    .blocks
3764                    .drain(self.blocks.len() - blocks..)
3765                    .collect::<Vec<_>>();
3766
3767                uwriteln!(self.src, "switch ((int32_t) {}) {{", operands[0]);
3768                for (i, (block, results)) in blocks.into_iter().enumerate() {
3769                    assert!(results.is_empty());
3770                    uwriteln!(self.src, "case {}: {{", i);
3771                    self.src.push_str(&block);
3772                    self.src.push_str("break;\n}\n");
3773                }
3774                self.src.push_str("}\n");
3775            }
3776            Instruction::GuestDeallocateList { element } => {
3777                let (body, results) = self.blocks.pop().unwrap();
3778                assert!(results.is_empty());
3779                let len = self.locals.tmp("len");
3780                uwriteln!(self.src, "size_t {len} = {};", operands[1]);
3781                uwriteln!(self.src, "if ({len} > 0) {{");
3782                let ptr = self.locals.tmp("ptr");
3783                uwriteln!(self.src, "uint8_t *{ptr} = {};", operands[0]);
3784                let i = self.locals.tmp("i");
3785                uwriteln!(self.src, "for (size_t {i} = 0; {i} < {len}; {i}++) {{");
3786                let size = self.r#gen.r#gen.sizes.size(element);
3787                uwriteln!(
3788                    self.src,
3789                    "uint8_t *base = {ptr} + {i} * {};",
3790                    size.format(POINTER_SIZE_EXPRESSION)
3791                );
3792                uwriteln!(self.src, "(void) base;");
3793                uwrite!(self.src, "{body}");
3794                uwriteln!(self.src, "}}");
3795                uwriteln!(self.src, "free({ptr});");
3796                uwriteln!(self.src, "}}");
3797            }
3798
3799            Instruction::Flush { amt } => {
3800                results.extend(operands.iter().take(*amt).map(|v| v.clone()));
3801            }
3802
3803            Instruction::AsyncTaskReturn { name, params } => {
3804                let body = match &mut self.deferred_task_return {
3805                    DeferredTaskReturn::Generating { prev_src } => {
3806                        mem::swap(&mut self.src, prev_src);
3807                        mem::take(prev_src)
3808                    }
3809                    _ => unreachable!(),
3810                };
3811                assert_eq!(params.len(), operands.len());
3812                self.deferred_task_return = DeferredTaskReturn::Emitted {
3813                    name: name.to_string(),
3814                    body,
3815                    params: params
3816                        .iter()
3817                        .zip(operands)
3818                        .map(|(a, b)| (a.clone(), b.clone()))
3819                        .collect(),
3820                };
3821            }
3822
3823            Instruction::FutureLift { .. } => {
3824                results.push(format!("((uint32_t) {})", operands[0]));
3825            }
3826            Instruction::FutureLower { .. } => {
3827                results.push(format!("((int32_t) {})", operands[0]));
3828            }
3829            Instruction::StreamLift { .. } => {
3830                results.push(format!("((uint32_t) {})", operands[0]));
3831            }
3832            Instruction::StreamLower { .. } => {
3833                results.push(format!("((int32_t) {})", operands[0]));
3834            }
3835
3836            i => unimplemented!("{:?}", i),
3837        }
3838    }
3839}
3840
3841#[derive(Default, Clone, Copy)]
3842enum SourceType {
3843    #[default]
3844    HDefs,
3845    HFns,
3846    // HHelpers,
3847    // CDefs,
3848    // CFns,
3849    // CHelpers,
3850    // CAdapters,
3851}
3852
3853#[derive(Default)]
3854struct Source {
3855    h_defs: wit_bindgen_core::Source,
3856    h_fns: wit_bindgen_core::Source,
3857    h_helpers: wit_bindgen_core::Source,
3858    h_async: wit_bindgen_core::Source,
3859    c_defs: wit_bindgen_core::Source,
3860    c_fns: wit_bindgen_core::Source,
3861    c_helpers: wit_bindgen_core::Source,
3862    c_adapters: wit_bindgen_core::Source,
3863    c_async: wit_bindgen_core::Source,
3864}
3865
3866impl Source {
3867    fn src(&mut self, stype: SourceType) -> &mut wit_bindgen_core::Source {
3868        match stype {
3869            SourceType::HDefs => &mut self.h_defs,
3870            SourceType::HFns => &mut self.h_fns,
3871        }
3872    }
3873    fn append(&mut self, append_src: &Source) {
3874        self.h_defs.push_str(&append_src.h_defs);
3875        self.h_fns.push_str(&append_src.h_fns);
3876        self.h_helpers.push_str(&append_src.h_helpers);
3877        self.h_async.push_str(&append_src.h_async);
3878        self.c_defs.push_str(&append_src.c_defs);
3879        self.c_fns.push_str(&append_src.c_fns);
3880        self.c_helpers.push_str(&append_src.c_helpers);
3881        self.c_adapters.push_str(&append_src.c_adapters);
3882        self.c_async.push_str(&append_src.c_async);
3883    }
3884    fn h_defs(&mut self, s: &str) {
3885        self.h_defs.push_str(s);
3886    }
3887    fn h_fns(&mut self, s: &str) {
3888        self.h_fns.push_str(s);
3889    }
3890    fn h_helpers(&mut self, s: &str) {
3891        self.h_helpers.push_str(s);
3892    }
3893    fn c_fns(&mut self, s: &str) {
3894        self.c_fns.push_str(s);
3895    }
3896    fn c_helpers(&mut self, s: &str) {
3897        self.c_helpers.push_str(s);
3898    }
3899    fn c_adapters(&mut self, s: &str) {
3900        self.c_adapters.push_str(s);
3901    }
3902}
3903
3904pub fn wasm_type(ty: WasmType) -> &'static str {
3905    match ty {
3906        WasmType::I32 => "int32_t",
3907        WasmType::I64 => "int64_t",
3908        WasmType::F32 => "float",
3909        WasmType::F64 => "double",
3910        WasmType::Pointer => "uint8_t *",
3911        WasmType::PointerOrI64 => "int64_t",
3912        WasmType::Length => "size_t",
3913    }
3914}
3915
3916pub fn int_repr(ty: Int) -> &'static str {
3917    match ty {
3918        Int::U8 => "uint8_t",
3919        Int::U16 => "uint16_t",
3920        Int::U32 => "uint32_t",
3921        Int::U64 => "uint64_t",
3922    }
3923}
3924
3925pub fn flags_repr(f: &Flags) -> Int {
3926    match f.repr() {
3927        FlagsRepr::U8 => Int::U8,
3928        FlagsRepr::U16 => Int::U16,
3929        FlagsRepr::U32(1) => Int::U32,
3930        FlagsRepr::U32(2) => Int::U64,
3931        repr => panic!("unimplemented flags {:?}", repr),
3932    }
3933}
3934
3935pub fn is_arg_by_pointer(resolve: &Resolve, ty: &Type) -> bool {
3936    match ty {
3937        Type::Id(id) => match resolve.types[*id].kind {
3938            TypeDefKind::Type(t) => is_arg_by_pointer(resolve, &t),
3939            TypeDefKind::Variant(_) => true,
3940            TypeDefKind::Option(_) => true,
3941            TypeDefKind::Result(_) => true,
3942            TypeDefKind::Enum(_) => false,
3943            TypeDefKind::Flags(_) => false,
3944            TypeDefKind::Handle(_) => false,
3945            TypeDefKind::Tuple(_) | TypeDefKind::Record(_) | TypeDefKind::List(_) => true,
3946            TypeDefKind::Future(_) => false,
3947            TypeDefKind::Stream(_) => false,
3948            TypeDefKind::Resource => todo!("is_arg_by_pointer for resource"),
3949            TypeDefKind::Unknown => unreachable!(),
3950            TypeDefKind::FixedSizeList(..) => todo!(),
3951        },
3952        Type::String => true,
3953        _ => false,
3954    }
3955}
3956
3957pub fn to_c_ident(name: &str) -> String {
3958    match name {
3959        // Escape C and C++ keywords.
3960        // Source: https://en.cppreference.com/w/cpp/keyword
3961        "alignas" => "alignas_".into(),
3962        "alignof" => "alignof_".into(),
3963        "and" => "and_".into(),
3964        "and_eq" => "and_eq_".into(),
3965        "asm" => "asm_".into(),
3966        "atomic_cancel" => "atomic_cancel_".into(),
3967        "atomic_commit" => "atomic_commit_".into(),
3968        "atomic_noexcept" => "atomic_noexcept_".into(),
3969        "auto" => "auto_".into(),
3970        "bitand" => "bitand_".into(),
3971        "bitor" => "bitor_".into(),
3972        "bool" => "bool_".into(),
3973        "break" => "break_".into(),
3974        "case" => "case_".into(),
3975        "catch" => "catch_".into(),
3976        "char" => "char_".into(),
3977        "char8_t" => "char8_t_".into(),
3978        "char16_t" => "char16_t_".into(),
3979        "char32_t" => "char32_t_".into(),
3980        "class" => "class_".into(),
3981        "compl" => "compl_".into(),
3982        "concept" => "concept_".into(),
3983        "const" => "const_".into(),
3984        "consteval" => "consteval_".into(),
3985        "constexpr" => "constexpr_".into(),
3986        "constinit" => "constinit_".into(),
3987        "const_cast" => "const_cast_".into(),
3988        "continue" => "continue_".into(),
3989        "co_await" => "co_await_".into(),
3990        "co_return" => "co_return_".into(),
3991        "co_yield" => "co_yield_".into(),
3992        "decltype" => "decltype_".into(),
3993        "default" => "default_".into(),
3994        "delete" => "delete_".into(),
3995        "do" => "do_".into(),
3996        "double" => "double_".into(),
3997        "dynamic_cast" => "dynamic_cast_".into(),
3998        "else" => "else_".into(),
3999        "enum" => "enum_".into(),
4000        "explicit" => "explicit_".into(),
4001        "export" => "export_".into(),
4002        "extern" => "extern_".into(),
4003        "false" => "false_".into(),
4004        "float" => "float_".into(),
4005        "for" => "for_".into(),
4006        "friend" => "friend_".into(),
4007        "goto" => "goto_".into(),
4008        "if" => "if_".into(),
4009        "inline" => "inline_".into(),
4010        "int" => "int_".into(),
4011        "long" => "long_".into(),
4012        "mutable" => "mutable_".into(),
4013        "namespace" => "namespace_".into(),
4014        "new" => "new_".into(),
4015        "noexcept" => "noexcept_".into(),
4016        "not" => "not_".into(),
4017        "not_eq" => "not_eq_".into(),
4018        "nullptr" => "nullptr_".into(),
4019        "operator" => "operator_".into(),
4020        "or" => "or_".into(),
4021        "or_eq" => "or_eq_".into(),
4022        "private" => "private_".into(),
4023        "protected" => "protected_".into(),
4024        "public" => "public_".into(),
4025        "reflexpr" => "reflexpr_".into(),
4026        "register" => "register_".into(),
4027        "reinterpret_cast" => "reinterpret_cast_".into(),
4028        "requires" => "requires_".into(),
4029        "return" => "return_".into(),
4030        "short" => "short_".into(),
4031        "signed" => "signed_".into(),
4032        "sizeof" => "sizeof_".into(),
4033        "static" => "static_".into(),
4034        "static_assert" => "static_assert_".into(),
4035        "static_cast" => "static_cast_".into(),
4036        "struct" => "struct_".into(),
4037        "switch" => "switch_".into(),
4038        "synchronized" => "synchronized_".into(),
4039        "template" => "template_".into(),
4040        "this" => "this_".into(),
4041        "thread_local" => "thread_local_".into(),
4042        "throw" => "throw_".into(),
4043        "true" => "true_".into(),
4044        "try" => "try_".into(),
4045        "typedef" => "typedef_".into(),
4046        "typeid" => "typeid_".into(),
4047        "typename" => "typename_".into(),
4048        "union" => "union_".into(),
4049        "unsigned" => "unsigned_".into(),
4050        "using" => "using_".into(),
4051        "virtual" => "virtual_".into(),
4052        "void" => "void_".into(),
4053        "volatile" => "volatile_".into(),
4054        "wchar_t" => "wchar_t_".into(),
4055        "while" => "while_".into(),
4056        "xor" => "xor_".into(),
4057        "xor_eq" => "xor_eq_".into(),
4058        "_Packed" => "_Packed_".into(),
4059        // ret and err needs to be escaped because they are used as
4060        //  variable names for option and result flattening.
4061        "ret" => "ret_".into(),
4062        "err" => "err_".into(),
4063        // C standard library macros that conflict when used as identifiers
4064        "stdin" => "stdin_".into(),
4065        "stdout" => "stdout_".into(),
4066        "stderr" => "stderr_".into(),
4067        s => s.to_snake_case(),
4068    }
4069}
4070
4071const POINTER_SIZE_EXPRESSION: &str = "sizeof(void*)";