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