Skip to main content

wit_bindgen_c/
lib.rs

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