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
1830pub enum CTypeNameInfo<'a> {
1831    Named { name: &'a str },
1832    Anonymous { is_prim: bool },
1833}
1834
1835/// Generate the type part of a c identifier, missing the namespace and the `_t` suffix.
1836/// Additionally return a `CTypeNameInfo` that describes what sort of name has been produced.
1837pub fn gen_type_name(resolve: &Resolve, ty: TypeId) -> (CTypeNameInfo<'_>, String) {
1838    let mut encoded = String::new();
1839    push_ty_name(resolve, &Type::Id(ty), &mut encoded);
1840    let info = if let Some(name) = &resolve.types[ty].name {
1841        CTypeNameInfo::Named {
1842            name: name.as_ref(),
1843        }
1844    } else {
1845        CTypeNameInfo::Anonymous {
1846            is_prim: is_prim_type_id(resolve, ty),
1847        }
1848    };
1849
1850    (info, encoded)
1851}
1852
1853impl InterfaceGenerator<'_> {
1854    fn define_interface_types(&mut self, id: InterfaceId) {
1855        let mut live = LiveTypes::default();
1856        live.add_interface(self.resolve, id);
1857        self.define_live_types(live);
1858    }
1859
1860    fn define_function_types(&mut self, funcs: &[(&str, &Function)]) {
1861        let mut live = LiveTypes::default();
1862        for (_, func) in funcs {
1863            live.add_func(self.resolve, func);
1864        }
1865        self.define_live_types(live);
1866    }
1867
1868    fn define_live_types(&mut self, live: LiveTypes) {
1869        for ty in live.iter() {
1870            if self.r#gen.type_names.contains_key(&ty) {
1871                continue;
1872            }
1873
1874            let (info, encoded) = gen_type_name(&self.resolve, ty);
1875            match info {
1876                CTypeNameInfo::Named { name } => {
1877                    let typedef_name = format!("{}_{encoded}_t", self.owner_namespace(ty));
1878                    let prev = self.r#gen.type_names.insert(ty, typedef_name.clone());
1879                    assert!(prev.is_none());
1880
1881                    self.define_type(name, ty)
1882                }
1883
1884                CTypeNameInfo::Anonymous { is_prim } => {
1885                    let (defined, name) = if is_prim {
1886                        let namespace = self.r#gen.world.to_snake_case();
1887                        let name = format!("{namespace}_{encoded}_t");
1888                        let new_prim = self.r#gen.prim_names.insert(name.clone());
1889                        (!new_prim, name)
1890                    } else {
1891                        let namespace = self.owner_namespace(ty);
1892                        (false, format!("{namespace}_{encoded}_t"))
1893                    };
1894
1895                    let prev = self.r#gen.type_names.insert(ty, name);
1896                    assert!(prev.is_none());
1897
1898                    if defined {
1899                        continue;
1900                    }
1901
1902                    let kind = &self.resolve.types[ty].kind;
1903                    if let TypeDefKind::Handle(handle) = kind {
1904                        let resource = match handle {
1905                            Handle::Borrow(id) | Handle::Own(id) => id,
1906                        };
1907                        let origin = dealias(self.resolve, *resource);
1908                        if origin == *resource {
1909                            continue;
1910                        }
1911                    }
1912
1913                    self.define_anonymous_type(ty)
1914                }
1915            }
1916
1917            self.define_dtor(ty);
1918        }
1919    }
1920
1921    fn define_dtor(&mut self, id: TypeId) {
1922        let h_helpers_start = self.src.h_helpers.len();
1923        let c_helpers_start = self.src.c_helpers.len();
1924
1925        let name = self.r#gen.type_names[&id].clone();
1926        let prefix = name.strip_suffix("_t").unwrap();
1927
1928        self.src
1929            .h_helpers(&format!("\nvoid {prefix}_free({name} *ptr);\n"));
1930        self.src
1931            .c_helpers(&format!("\nvoid {prefix}_free({name} *ptr) {{\n"));
1932        let c_helpers_body_start = self.src.c_helpers.len();
1933        match &self.resolve.types[id].kind {
1934            TypeDefKind::Type(t) => self.free(t, "ptr"),
1935
1936            TypeDefKind::Flags(_) => {}
1937            TypeDefKind::Enum(_) => {}
1938
1939            TypeDefKind::Record(r) => {
1940                for field in r.fields.iter() {
1941                    self.free(&field.ty, &format!("&ptr->{}", to_c_ident(&field.name)));
1942                }
1943            }
1944
1945            TypeDefKind::Tuple(t) => {
1946                for (i, ty) in t.types.iter().enumerate() {
1947                    self.free(ty, &format!("&ptr->f{i}"));
1948                }
1949            }
1950
1951            TypeDefKind::List(t) => {
1952                self.src.c_helpers("size_t list_len = ptr->len;\n");
1953                uwriteln!(self.src.c_helpers, "if (list_len > 0) {{");
1954                let mut t_name = String::new();
1955                self.r#gen.push_type_name(t, &mut t_name);
1956                self.src
1957                    .c_helpers(&format!("{t_name} *list_ptr = ptr->ptr;\n"));
1958                self.src
1959                    .c_helpers("for (size_t i = 0; i < list_len; i++) {\n");
1960                self.free(t, "&list_ptr[i]");
1961                self.src.c_helpers("}\n");
1962                uwriteln!(self.src.c_helpers, "free(list_ptr);");
1963                uwriteln!(self.src.c_helpers, "}}");
1964            }
1965
1966            TypeDefKind::Variant(v) => {
1967                self.src.c_helpers("switch ((int32_t) ptr->tag) {\n");
1968                for (i, case) in v.cases.iter().enumerate() {
1969                    if let Some(ty) = &case.ty {
1970                        uwriteln!(self.src.c_helpers, "case {}: {{", i);
1971                        let expr = format!("&ptr->val.{}", to_c_ident(&case.name));
1972                        self.free(ty, &expr);
1973                        self.src.c_helpers("break;\n");
1974                        self.src.c_helpers("}\n");
1975                    }
1976                }
1977                self.src.c_helpers("}\n");
1978            }
1979
1980            TypeDefKind::Option(t) => {
1981                self.src.c_helpers("if (ptr->is_some) {\n");
1982                self.free(t, "&ptr->val");
1983                self.src.c_helpers("}\n");
1984            }
1985
1986            TypeDefKind::Result(r) => {
1987                self.src.c_helpers("if (!ptr->is_err) {\n");
1988                if let Some(ok) = &r.ok {
1989                    self.free(ok, "&ptr->val.ok");
1990                }
1991                if let Some(err) = &r.err {
1992                    self.src.c_helpers("} else {\n");
1993                    self.free(err, "&ptr->val.err");
1994                }
1995                self.src.c_helpers("}\n");
1996            }
1997            TypeDefKind::Future(_) | TypeDefKind::Stream(_) => {
1998                self.free(&Type::Id(id), "*ptr");
1999            }
2000            TypeDefKind::Resource => {}
2001            TypeDefKind::Handle(Handle::Borrow(id) | Handle::Own(id)) => {
2002                self.free(&Type::Id(*id), "*ptr");
2003            }
2004            TypeDefKind::Unknown => unreachable!(),
2005            TypeDefKind::FixedSizeList(..) => todo!(),
2006            TypeDefKind::Map(..) => todo!(),
2007        }
2008        if c_helpers_body_start == self.src.c_helpers.len() {
2009            self.src.c_helpers.as_mut_string().truncate(c_helpers_start);
2010            self.src.h_helpers.as_mut_string().truncate(h_helpers_start);
2011            return;
2012        }
2013        self.src.c_helpers("}\n");
2014        self.r#gen.dtor_funcs.insert(id, format!("{prefix}_free"));
2015    }
2016
2017    fn free(&mut self, ty: &Type, expr: &str) {
2018        match ty {
2019            Type::Id(id) => {
2020                if let Some(dtor) = self.r#gen.dtor_funcs.get(&id) {
2021                    self.src.c_helpers(&format!("{dtor}({expr});\n"));
2022                }
2023            }
2024            Type::String => {
2025                let snake = self.r#gen.world.to_snake_case();
2026                self.src
2027                    .c_helpers(&format!("{snake}_string_free({expr});\n"));
2028            }
2029            Type::Bool
2030            | Type::U8
2031            | Type::S8
2032            | Type::U16
2033            | Type::S16
2034            | Type::U32
2035            | Type::S32
2036            | Type::U64
2037            | Type::S64
2038            | Type::F32
2039            | Type::F64
2040            | Type::Char => {}
2041            Type::ErrorContext => todo!("error context free"),
2042        }
2043    }
2044
2045    fn c_func_name(&self, interface_id: Option<&WorldKey>, func: &Function) -> String {
2046        c_func_name(
2047            self.in_import,
2048            self.resolve,
2049            &self.r#gen.world,
2050            interface_id,
2051            func,
2052            &self.r#gen.renamed_interfaces,
2053        )
2054    }
2055
2056    fn import(&mut self, interface_name: Option<&WorldKey>, func: &Function) {
2057        let async_ = self
2058            .r#gen
2059            .opts
2060            .async_
2061            .is_async(self.resolve, interface_name, func, true);
2062        if async_ {
2063            self.r#gen.needs_async = true;
2064        }
2065
2066        self.docs(&func.docs, SourceType::HFns);
2067        let (variant, import_prefix) = if async_ {
2068            (AbiVariant::GuestImportAsync, "[async-lower]")
2069        } else {
2070            (AbiVariant::GuestImport, "")
2071        };
2072        let sig = self.resolve.wasm_signature(variant, func);
2073
2074        self.src.c_fns("\n");
2075
2076        // In the private C file, print a function declaration which is the
2077        // actual wasm import that we'll be calling, and this has the raw wasm
2078        // signature.
2079        uwriteln!(
2080            self.src.c_fns,
2081            "__attribute__((__import_module__(\"{}\"), __import_name__(\"{import_prefix}{}\")))",
2082            match interface_name {
2083                Some(name) => self.resolve.name_world_key(name),
2084                None => "$root".to_string(),
2085            },
2086            func.name
2087        );
2088        let name = self.c_func_name(interface_name, func);
2089        let import_name = self.r#gen.names.tmp(&format!("__wasm_import_{name}",));
2090        self.src.c_fns("extern ");
2091        match sig.results.len() {
2092            0 => self.src.c_fns("void"),
2093            1 => self.src.c_fns(wasm_type(sig.results[0])),
2094            _ => unimplemented!("multi-value return not supported"),
2095        }
2096        self.src.c_fns(" ");
2097        self.src.c_fns(&import_name);
2098        self.src.c_fns("(");
2099        for (i, param) in sig.params.iter().enumerate() {
2100            if i > 0 {
2101                self.src.c_fns(", ");
2102            }
2103            self.src.c_fns(wasm_type(*param));
2104        }
2105        if sig.params.len() == 0 {
2106            self.src.c_fns("void");
2107        }
2108        self.src.c_fns(");\n");
2109
2110        // Print the public facing signature into the header, and since that's
2111        // what we are defining also print it into the C file.
2112        self.src.h_fns("extern ");
2113        let c_sig = self.print_sig(interface_name, func, &sig, async_);
2114        self.src.c_adapters("\n");
2115        self.src.c_adapters(&c_sig.sig);
2116        self.src.c_adapters(" {\n");
2117
2118        if async_ {
2119            self.import_body_async(func, c_sig, &sig, &import_name);
2120        } else {
2121            self.import_body_sync(func, c_sig, &import_name);
2122        }
2123
2124        self.src.c_adapters("}\n");
2125
2126        self.generate_async_futures_and_streams("", func, interface_name);
2127    }
2128
2129    fn import_body_sync(&mut self, func: &Function, c_sig: CSig, import_name: &str) {
2130        // construct optional adapters from maybe pointers to real optional
2131        // structs internally
2132        let mut optional_adapters = String::from("");
2133        if !self.r#gen.opts.no_sig_flattening {
2134            for (i, (_, param)) in c_sig.params.iter().enumerate() {
2135                let ty = &func.params[i].1;
2136                if let Type::Id(id) = ty {
2137                    if let TypeDefKind::Option(_) = &self.resolve.types[*id].kind {
2138                        let ty = self.r#gen.type_name(ty);
2139                        uwrite!(
2140                            optional_adapters,
2141                            "{ty} {param};
2142                            {param}.is_some = maybe_{param} != NULL;"
2143                        );
2144                        uwriteln!(
2145                            optional_adapters,
2146                            "if (maybe_{param}) {{
2147                                {param}.val = *maybe_{param};
2148                            }}",
2149                        );
2150                    }
2151                }
2152            }
2153        }
2154
2155        let mut f = FunctionBindgen::new(self, c_sig, &import_name);
2156        for (pointer, param) in f.sig.params.iter() {
2157            if *pointer {
2158                f.params.push(format!("*{param}"));
2159            } else {
2160                f.params.push(param.clone());
2161            }
2162        }
2163        for ptr in f.sig.retptrs.iter() {
2164            f.locals.insert(ptr).unwrap();
2165        }
2166        f.src.push_str(&optional_adapters);
2167        abi::call(
2168            f.r#gen.resolve,
2169            AbiVariant::GuestImport,
2170            LiftLower::LowerArgsLiftResults,
2171            func,
2172            &mut f,
2173            false,
2174        );
2175
2176        let FunctionBindgen {
2177            src,
2178            import_return_pointer_area_size,
2179            import_return_pointer_area_align,
2180            ..
2181        } = f;
2182
2183        if !import_return_pointer_area_size.is_empty() {
2184            self.src.c_adapters(&format!(
2185                "\
2186                    __attribute__((__aligned__({})))
2187                    uint8_t ret_area[{}];
2188                ",
2189                import_return_pointer_area_align.format(POINTER_SIZE_EXPRESSION),
2190                import_return_pointer_area_size.format(POINTER_SIZE_EXPRESSION),
2191            ));
2192        }
2193
2194        self.src.c_adapters(&String::from(src));
2195    }
2196
2197    fn import_body_async(
2198        &mut self,
2199        func: &Function,
2200        c_sig: CSig,
2201        wasm_sig: &WasmSignature,
2202        import_name: &str,
2203    ) {
2204        let mut params = Vec::new();
2205        if wasm_sig.indirect_params {
2206            params.push(format!("(uint8_t*) {}", c_sig.params[0].1));
2207        } else {
2208            let mut f = FunctionBindgen::new(self, c_sig.clone(), "INVALID");
2209            for (i, (_, ty)) in func.params.iter().enumerate() {
2210                let param = &c_sig.params[i].1;
2211                params.extend(abi::lower_flat(f.r#gen.resolve, &mut f, param.clone(), ty));
2212            }
2213            f.r#gen.src.c_adapters.push_str(&f.src);
2214        }
2215        if func.result.is_some() {
2216            params.push(format!("(uint8_t*) {}", c_sig.params.last().unwrap().1));
2217        }
2218        uwriteln!(
2219            self.src.c_adapters,
2220            "return {import_name}({});",
2221            params.join(", "),
2222        );
2223    }
2224
2225    fn export(&mut self, func: &Function, interface_name: Option<&WorldKey>) {
2226        let async_ = self
2227            .r#gen
2228            .opts
2229            .async_
2230            .is_async(self.resolve, interface_name, func, false);
2231
2232        let (variant, prefix) = if async_ {
2233            self.r#gen.needs_async = true;
2234            (AbiVariant::GuestExportAsync, "[async-lift]")
2235        } else {
2236            (AbiVariant::GuestExport, "")
2237        };
2238
2239        let sig = self.resolve.wasm_signature(variant, func);
2240
2241        self.src.c_fns("\n");
2242
2243        let core_module_name = interface_name.map(|s| self.resolve.name_world_key(s));
2244        let export_name = func.legacy_core_export_name(core_module_name.as_deref());
2245
2246        // Print the actual header for this function into the header file, and
2247        // it's what we'll be calling.
2248        let h_sig = self.print_sig(interface_name, func, &sig, async_);
2249
2250        // Generate, in the C source file, the raw wasm signature that has the
2251        // canonical ABI.
2252        uwriteln!(
2253            self.src.c_adapters,
2254            "\n__attribute__((__export_name__(\"{prefix}{export_name}\")))"
2255        );
2256        let name = self.c_func_name(interface_name, func);
2257        let import_name = self.r#gen.names.tmp(&format!("__wasm_export_{name}"));
2258
2259        let mut f = FunctionBindgen::new(self, h_sig, &import_name);
2260        match sig.results.len() {
2261            0 => f.r#gen.src.c_adapters("void"),
2262            1 => f.r#gen.src.c_adapters(wasm_type(sig.results[0])),
2263            _ => unimplemented!("multi-value return not supported"),
2264        }
2265        f.r#gen.src.c_adapters(" ");
2266        f.r#gen.src.c_adapters(&import_name);
2267        f.r#gen.src.c_adapters("(");
2268        for (i, param) in sig.params.iter().enumerate() {
2269            if i > 0 {
2270                f.r#gen.src.c_adapters(", ");
2271            }
2272            let name = f.locals.tmp("arg");
2273            uwrite!(f.r#gen.src.c_adapters, "{} {}", wasm_type(*param), name);
2274            f.params.push(name);
2275        }
2276        if sig.params.len() == 0 {
2277            f.r#gen.src.c_adapters("void");
2278        }
2279        f.r#gen.src.c_adapters(") {\n");
2280
2281        // Perform all lifting/lowering and append it to our src.
2282        abi::call(
2283            f.r#gen.resolve,
2284            variant,
2285            LiftLower::LiftArgsLowerResults,
2286            func,
2287            &mut f,
2288            async_,
2289        );
2290        let FunctionBindgen {
2291            src,
2292            deferred_task_return,
2293            ..
2294        } = f;
2295        self.src.c_adapters(&src);
2296        self.src.c_adapters("}\n");
2297
2298        if async_ {
2299            let snake = self.r#gen.world.to_snake_case();
2300            let return_ty = match &func.result {
2301                Some(ty) => format!("{} ret", self.r#gen.type_name(ty)),
2302                None => "void".to_string(),
2303            };
2304            let DeferredTaskReturn::Emitted {
2305                body: mut task_return_body,
2306                name: task_return_name,
2307                params: task_return_params,
2308            } = deferred_task_return
2309            else {
2310                unreachable!()
2311            };
2312            let task_return_param_tys = task_return_params
2313                .iter()
2314                .map(|(ty, _expr)| wasm_type(*ty))
2315                .collect::<Vec<_>>()
2316                .join(", ");
2317            let task_return_param_exprs = task_return_params
2318                .iter()
2319                .map(|(_ty, expr)| expr.as_str())
2320                .collect::<Vec<_>>()
2321                .join(", ");
2322            let task_return_body = task_return_body.as_mut_string();
2323            uwriteln!(
2324                self.src.h_fns,
2325                "{snake}_callback_code_t {name}_callback({snake}_event_t *event);",
2326            );
2327            uwriteln!(self.src.h_helpers, "void {name}_return({return_ty});");
2328            let import_module = match interface_name {
2329                Some(name) => self.resolve.name_world_key(name),
2330                None => "$root".to_string(),
2331            };
2332            uwriteln!(
2333                self.src.c_helpers,
2334                r#"
2335__attribute__((__export_name__("[callback]{prefix}{export_name}")))
2336uint32_t {import_name}_callback(uint32_t event_raw, uint32_t waitable, uint32_t code) {{
2337    {snake}_event_t event;
2338    event.event = ({snake}_event_code_t) event_raw;
2339    event.waitable = waitable;
2340    event.code = code;
2341    return {name}_callback(&event);
2342}}
2343
2344__attribute__((__import_module__("[export]{import_module}"), __import_name__("{task_return_name}")))
2345void {import_name}__task_return({task_return_param_tys});
2346
2347void {name}_return({return_ty}) {{
2348    {task_return_body}
2349    {import_name}__task_return({task_return_param_exprs});
2350}}
2351                "#
2352            );
2353        } else if abi::guest_export_needs_post_return(self.resolve, func) {
2354            uwriteln!(
2355                self.src.c_fns,
2356                "__attribute__((__weak__, __export_name__(\"cabi_post_{export_name}\")))"
2357            );
2358            uwrite!(self.src.c_fns, "void {import_name}_post_return(");
2359
2360            let mut params = Vec::new();
2361            let mut c_sig = CSig {
2362                name: String::from("INVALID"),
2363                sig: String::from("INVALID"),
2364                params: Vec::new(),
2365                ret: Return::default(),
2366                retptrs: Vec::new(),
2367            };
2368            for (i, result) in sig.results.iter().enumerate() {
2369                let name = format!("arg{i}");
2370                uwrite!(self.src.c_fns, "{} {name}", wasm_type(*result));
2371                c_sig.params.push((false, name.clone()));
2372                params.push(name);
2373            }
2374            self.src.c_fns.push_str(") {\n");
2375
2376            let mut f = FunctionBindgen::new(self, c_sig, &import_name);
2377            f.params = params;
2378            abi::post_return(f.r#gen.resolve, func, &mut f);
2379            let FunctionBindgen { src, .. } = f;
2380            self.src.c_fns(&src);
2381            self.src.c_fns("}\n");
2382        }
2383
2384        self.generate_async_futures_and_streams("[export]", func, interface_name);
2385    }
2386
2387    fn print_sig(
2388        &mut self,
2389        interface_name: Option<&WorldKey>,
2390        func: &Function,
2391        sig: &WasmSignature,
2392        async_: bool,
2393    ) -> CSig {
2394        let name = self.c_func_name(interface_name, func);
2395        self.r#gen.names.insert(&name).expect("duplicate symbols");
2396
2397        let start = self.src.h_fns.len();
2398        let mut result_rets = false;
2399        let mut result_rets_has_ok_type = false;
2400
2401        let ret = if async_ && !self.in_import {
2402            Return {
2403                scalar: func.result.map(Scalar::Type),
2404                retptrs: Vec::new(),
2405            }
2406        } else {
2407            self.classify_ret(func)
2408        };
2409        if async_ {
2410            let snake = self.r#gen.world.to_snake_case();
2411            if self.in_import {
2412                uwrite!(self.src.h_fns, "{snake}_subtask_status_t");
2413            } else {
2414                uwrite!(self.src.h_fns, "{snake}_callback_code_t");
2415            }
2416        } else {
2417            match &ret.scalar {
2418                None | Some(Scalar::Void) => self.src.h_fns("void"),
2419                Some(Scalar::OptionBool(_id)) => self.src.h_fns("bool"),
2420                Some(Scalar::ResultBool(ok, _err)) => {
2421                    result_rets = true;
2422                    result_rets_has_ok_type = ok.is_some();
2423                    self.src.h_fns("bool");
2424                }
2425                Some(Scalar::Type(ty)) => self.print_ty(SourceType::HFns, ty),
2426            }
2427        }
2428        self.src.h_fns(" ");
2429        self.src.h_fns(&name);
2430        self.src.h_fns("(");
2431        let params;
2432        let mut retptrs = Vec::new();
2433        if async_ && self.in_import {
2434            params = self.print_sig_async_import_params(&name, func, sig);
2435        } else if async_ && !self.in_import {
2436            params = self.print_sig_params(func);
2437        } else {
2438            params = self.print_sig_params(func);
2439            let single_ret = ret.retptrs.len() == 1;
2440            for (i, ty) in ret.retptrs.iter().enumerate() {
2441                if i > 0 || func.params.len() > 0 {
2442                    self.src.h_fns(", ");
2443                }
2444                self.print_ty(SourceType::HFns, ty);
2445                self.src.h_fns(" *");
2446                let name: String = if result_rets {
2447                    assert!(i <= 1);
2448                    if i == 0 && result_rets_has_ok_type {
2449                        "ret".into()
2450                    } else {
2451                        "err".into()
2452                    }
2453                } else if single_ret {
2454                    "ret".into()
2455                } else {
2456                    format!("ret{i}")
2457                };
2458                self.src.h_fns(&name);
2459                retptrs.push(name);
2460            }
2461            if func.params.len() == 0 && ret.retptrs.len() == 0 {
2462                self.src.h_fns("void");
2463            }
2464        }
2465        self.src.h_fns(")");
2466
2467        let sig = self.src.h_fns[start..].to_string();
2468        self.src.h_fns(";\n");
2469
2470        CSig {
2471            sig,
2472            name,
2473            params,
2474            ret,
2475            retptrs,
2476        }
2477    }
2478
2479    fn print_sig_params(&mut self, func: &Function) -> Vec<(bool, String)> {
2480        let mut params = Vec::new();
2481        for (i, (name, ty)) in func.params.iter().enumerate() {
2482            if i > 0 {
2483                self.src.h_fns(", ");
2484            }
2485            let pointer = is_arg_by_pointer(self.resolve, ty);
2486            // optional param pointer sig_flattening
2487            let optional_type = if let Type::Id(id) = ty {
2488                if let TypeDefKind::Option(option_ty) = &self.resolve.types[*id].kind {
2489                    if !self.r#gen.opts.no_sig_flattening {
2490                        Some(option_ty)
2491                    } else {
2492                        None
2493                    }
2494                } else {
2495                    None
2496                }
2497            } else {
2498                None
2499            };
2500            let (print_ty, print_name) = if !self.r#gen.opts.no_sig_flattening {
2501                if let Some(option_ty) = optional_type {
2502                    (option_ty, format!("maybe_{}", to_c_ident(name)))
2503                } else {
2504                    (ty, to_c_ident(name))
2505                }
2506            } else {
2507                (ty, to_c_ident(name))
2508            };
2509            self.print_ty(SourceType::HFns, print_ty);
2510            self.src.h_fns(" ");
2511            if pointer {
2512                self.src.h_fns("*");
2513            }
2514            self.src.h_fns(&print_name);
2515            params.push((optional_type.is_none() && pointer, to_c_ident(name)));
2516        }
2517        params
2518    }
2519
2520    fn print_sig_async_import_params(
2521        &mut self,
2522        c_func_name: &str,
2523        func: &Function,
2524        sig: &WasmSignature,
2525    ) -> Vec<(bool, String)> {
2526        let mut params = Vec::new();
2527        let mut printed = false;
2528        if sig.indirect_params {
2529            match &func.params[..] {
2530                [] => {}
2531                [(_name, ty)] => {
2532                    printed = true;
2533                    let name = "arg".to_string();
2534                    self.print_ty(SourceType::HFns, ty);
2535                    self.src.h_fns(" *");
2536                    self.src.h_fns(&name);
2537                    params.push((true, name));
2538                }
2539                multiple => {
2540                    printed = true;
2541                    let names = multiple
2542                        .iter()
2543                        .map(|(name, ty)| (to_c_ident(name), self.r#gen.type_name(ty)))
2544                        .collect::<Vec<_>>();
2545                    uwriteln!(self.src.h_defs, "typedef struct {c_func_name}_args {{");
2546                    for (name, ty) in names {
2547                        uwriteln!(self.src.h_defs, "{ty} {name};");
2548                    }
2549                    uwriteln!(self.src.h_defs, "}} {c_func_name}_args_t;");
2550                    uwrite!(self.src.h_fns, "{c_func_name}_args_t *args");
2551                    params.push((true, "args".to_string()));
2552                }
2553            }
2554        } else {
2555            for (name, ty) in func.params.iter() {
2556                let name = to_c_ident(name);
2557                if printed {
2558                    self.src.h_fns(", ");
2559                } else {
2560                    printed = true;
2561                }
2562                self.print_ty(SourceType::HFns, ty);
2563                self.src.h_fns(" ");
2564                self.src.h_fns(&name);
2565                params.push((false, name));
2566            }
2567        }
2568        if let Some(ty) = &func.result {
2569            if printed {
2570                self.src.h_fns(", ");
2571            } else {
2572                printed = true;
2573            }
2574            let name = "result".to_string();
2575            self.print_ty(SourceType::HFns, ty);
2576            self.src.h_fns(" *");
2577            self.src.h_fns(&name);
2578            params.push((true, name));
2579        }
2580        if !printed {
2581            self.src.h_fns("void");
2582        }
2583        params
2584    }
2585
2586    fn classify_ret(&mut self, func: &Function) -> Return {
2587        let mut ret = Return::default();
2588        match &func.result {
2589            None => ret.scalar = Some(Scalar::Void),
2590            Some(ty) => {
2591                ret.return_single(self.resolve, ty, ty, !self.r#gen.opts.no_sig_flattening);
2592            }
2593        }
2594        return ret;
2595    }
2596
2597    fn print_typedef_target(&mut self, id: TypeId) {
2598        let name = &self.r#gen.type_names[&id];
2599        self.src.h_defs(&name);
2600        self.src.h_defs(";\n");
2601    }
2602
2603    fn start_typedef_struct(&mut self, id: TypeId) {
2604        let name = &self.r#gen.type_names[&id];
2605        self.src.h_defs("typedef struct ");
2606        self.src.h_defs(&name);
2607        self.src.h_defs(" {\n");
2608    }
2609
2610    fn finish_typedef_struct(&mut self, id: TypeId) {
2611        self.src.h_defs("} ");
2612        self.print_typedef_target(id);
2613    }
2614
2615    fn owner_namespace(&self, id: TypeId) -> String {
2616        owner_namespace(
2617            self.interface,
2618            self.in_import,
2619            self.r#gen.world.clone(),
2620            self.resolve,
2621            id,
2622            &self.r#gen.renamed_interfaces,
2623        )
2624    }
2625
2626    fn print_ty(&mut self, stype: SourceType, ty: &Type) {
2627        self.r#gen
2628            .push_type_name(ty, self.src.src(stype).as_mut_string());
2629    }
2630
2631    fn docs(&mut self, docs: &Docs, stype: SourceType) {
2632        let docs = match &docs.contents {
2633            Some(docs) => docs,
2634            None => return,
2635        };
2636        let src = self.src.src(stype);
2637        for line in docs.trim().lines() {
2638            src.push_str("// ");
2639            src.push_str(line);
2640            src.push_str("\n");
2641        }
2642    }
2643
2644    fn autodrop_enabled(&self) -> bool {
2645        self.r#gen.opts.autodrop_borrows == Enabled::Yes
2646    }
2647
2648    fn contains_droppable_borrow(&self, ty: &Type) -> bool {
2649        if let Type::Id(id) = ty {
2650            match &self.resolve.types[*id].kind {
2651                TypeDefKind::Handle(h) => match h {
2652                    // Handles to imported resources will need to be dropped, if the context
2653                    // they're used in is an export.
2654                    Handle::Borrow(id) => {
2655                        !self.in_import
2656                            && matches!(
2657                                self.r#gen.resources[&dealias(self.resolve, *id)].direction,
2658                                Direction::Import
2659                            )
2660                    }
2661
2662                    Handle::Own(_) => false,
2663                },
2664
2665                TypeDefKind::Resource | TypeDefKind::Flags(_) | TypeDefKind::Enum(_) => false,
2666
2667                TypeDefKind::Record(r) => r
2668                    .fields
2669                    .iter()
2670                    .any(|f| self.contains_droppable_borrow(&f.ty)),
2671
2672                TypeDefKind::Tuple(t) => {
2673                    t.types.iter().any(|ty| self.contains_droppable_borrow(ty))
2674                }
2675
2676                TypeDefKind::Variant(v) => v.cases.iter().any(|case| {
2677                    case.ty
2678                        .as_ref()
2679                        .map_or(false, |ty| self.contains_droppable_borrow(ty))
2680                }),
2681
2682                TypeDefKind::Option(ty) => self.contains_droppable_borrow(ty),
2683
2684                TypeDefKind::Result(r) => {
2685                    r.ok.as_ref()
2686                        .map_or(false, |ty| self.contains_droppable_borrow(ty))
2687                        || r.err
2688                            .as_ref()
2689                            .map_or(false, |ty| self.contains_droppable_borrow(ty))
2690                }
2691
2692                TypeDefKind::List(ty) => self.contains_droppable_borrow(ty),
2693
2694                TypeDefKind::Future(_) | TypeDefKind::Stream(_) => false,
2695
2696                TypeDefKind::Type(ty) => self.contains_droppable_borrow(ty),
2697
2698                TypeDefKind::Unknown => false,
2699                TypeDefKind::FixedSizeList(..) => todo!(),
2700                TypeDefKind::Map(..) => todo!(),
2701            }
2702        } else {
2703            false
2704        }
2705    }
2706
2707    fn generate_async_futures_and_streams(
2708        &mut self,
2709        prefix: &str,
2710        func: &Function,
2711        interface: Option<&WorldKey>,
2712    ) {
2713        let module = format!(
2714            "{prefix}{}",
2715            interface
2716                .map(|name| self.resolve.name_world_key(name))
2717                .unwrap_or_else(|| "$root".into())
2718        );
2719        for (index, ty) in func
2720            .find_futures_and_streams(self.resolve)
2721            .into_iter()
2722            .enumerate()
2723        {
2724            let func_name = &func.name;
2725
2726            match &self.resolve.types[ty].kind {
2727                TypeDefKind::Future(payload_type) => {
2728                    self.generate_async_future_or_stream(
2729                        PayloadFor::Future,
2730                        &module,
2731                        index,
2732                        func_name,
2733                        ty,
2734                        payload_type.as_ref(),
2735                    );
2736                }
2737                TypeDefKind::Stream(payload_type) => {
2738                    self.generate_async_future_or_stream(
2739                        PayloadFor::Stream,
2740                        &module,
2741                        index,
2742                        func_name,
2743                        ty,
2744                        payload_type.as_ref(),
2745                    );
2746                }
2747                _ => unreachable!(),
2748            }
2749        }
2750    }
2751
2752    fn generate_async_future_or_stream(
2753        &mut self,
2754        payload_for: PayloadFor,
2755        module: &str,
2756        index: usize,
2757        func_name: &str,
2758        ty: TypeId,
2759        payload_type: Option<&Type>,
2760    ) {
2761        if !self.r#gen.futures.insert(ty) {
2762            return;
2763        }
2764        let ty = self.r#gen.type_name(&Type::Id(ty));
2765        let name = ty.strip_suffix("_t").unwrap();
2766        let snake = self.r#gen.world.to_snake_case();
2767        let kind = match payload_for {
2768            PayloadFor::Future => "future",
2769            PayloadFor::Stream => "stream",
2770        };
2771        let payload_len_arg = match payload_for {
2772            PayloadFor::Future => "",
2773            PayloadFor::Stream => ", size_t",
2774        };
2775        let (read_arg_ty, read_arg_expr, write_arg_ty, write_arg_expr) =
2776            match (payload_for, payload_type) {
2777                (PayloadFor::Future, None) => ("".to_string(), "NULL", "".to_string(), "NULL"),
2778                (PayloadFor::Future, Some(ty)) => {
2779                    let ty = self.r#gen.type_name(ty);
2780                    (
2781                        format!(", {ty} *buf"),
2782                        "(uint8_t*) buf",
2783                        format!(", const {ty} *buf"),
2784                        "(const uint8_t*) buf",
2785                    )
2786                }
2787                (PayloadFor::Stream, None) => (
2788                    ", size_t amt".to_string(),
2789                    "NULL, amt",
2790                    ", size_t amt".to_string(),
2791                    "NULL, amt",
2792                ),
2793                (PayloadFor::Stream, Some(ty)) => {
2794                    let ty = self.r#gen.type_name(ty);
2795                    (
2796                        format!(", {ty} *buf, size_t amt"),
2797                        "(uint8_t*) buf, amt",
2798                        format!(", const {ty} *buf, size_t amt"),
2799                        "(const uint8_t*) buf, amt",
2800                    )
2801                }
2802            };
2803
2804        // TODO: this is a hack around space-stripping in `source.rs`, ideally
2805        // wouldn't be necessary.
2806        let empty = "";
2807        uwriteln!(
2808            self.src.h_helpers,
2809            r#"
2810typedef uint32_t {name}_writer_t;
2811
2812{ty} {name}_new({name}_writer_t *writer);
2813{snake}_waitable_status_t {name}_read({ty} reader{read_arg_ty});
2814{snake}_waitable_status_t {name}_write({name}_writer_t writer{write_arg_ty});
2815{snake}_waitable_status_t {name}_cancel_read({ty} reader);
2816{snake}_waitable_status_t {name}_cancel_write({name}_writer_t writer);
2817void {name}_drop_readable({ty} reader);{empty}
2818void {name}_drop_writable({name}_writer_t writer);
2819            "#,
2820        );
2821        uwriteln!(
2822            self.src.c_helpers,
2823            r#"
2824__attribute__((__import_module__("{module}"), __import_name__("[{kind}-new-{index}]{func_name}")))
2825extern uint64_t {name}__new(void);
2826__attribute__((__import_module__("{module}"), __import_name__("[async-lower][{kind}-read-{index}]{func_name}")))
2827extern uint32_t {name}__read(uint32_t, uint8_t*{payload_len_arg});
2828__attribute__((__import_module__("{module}"), __import_name__("[async-lower][{kind}-write-{index}]{func_name}")))
2829extern uint32_t {name}__write(uint32_t, const uint8_t*{payload_len_arg});
2830__attribute__((__import_module__("{module}"), __import_name__("[{kind}-cancel-read-{index}]{func_name}")))
2831extern uint32_t {name}__cancel_read(uint32_t);
2832__attribute__((__import_module__("{module}"), __import_name__("[{kind}-cancel-write-{index}]{func_name}")))
2833extern uint32_t {name}__cancel_write(uint32_t);
2834__attribute__((__import_module__("{module}"), __import_name__("[{kind}-drop-readable-{index}]{func_name}")))
2835extern void {name}__drop_readable(uint32_t);
2836__attribute__((__import_module__("{module}"), __import_name__("[{kind}-drop-writable-{index}]{func_name}")))
2837extern void {name}__drop_writable(uint32_t);
2838
2839{ty} {name}_new({name}_writer_t *writer) {{
2840    uint64_t packed = {name}__new();
2841    *writer = (uint32_t) (packed >> 32);
2842    return (uint32_t) packed;
2843}}
2844
2845{snake}_waitable_status_t {name}_read({ty} reader{read_arg_ty}) {{
2846    return {name}__read(reader, {read_arg_expr});
2847}}
2848
2849{snake}_waitable_status_t {name}_write({name}_writer_t writer{write_arg_ty}) {{
2850    return {name}__write(writer, {write_arg_expr});
2851}}
2852
2853{snake}_waitable_status_t {name}_cancel_read({ty} reader){empty} {{
2854    return {name}__cancel_read(reader);
2855}}
2856
2857{snake}_waitable_status_t {name}_cancel_write({name}_writer_t writer) {{
2858    return {name}__cancel_write(writer);
2859}}
2860
2861void {name}_drop_readable({ty} reader){empty} {{
2862    {name}__drop_readable(reader);
2863}}
2864
2865void {name}_drop_writable({name}_writer_t writer) {{
2866    {name}__drop_writable(writer);
2867}}
2868            "#,
2869        );
2870    }
2871}
2872
2873enum PayloadFor {
2874    Future,
2875    Stream,
2876}
2877
2878struct DroppableBorrow {
2879    name: String,
2880    ty: TypeId,
2881}
2882
2883struct FunctionBindgen<'a, 'b> {
2884    r#gen: &'a mut InterfaceGenerator<'b>,
2885    locals: Ns,
2886    src: wit_bindgen_core::Source,
2887    sig: CSig,
2888    func_to_call: &'a str,
2889    block_storage: Vec<wit_bindgen_core::Source>,
2890    blocks: Vec<(String, Vec<String>)>,
2891    payloads: Vec<String>,
2892    params: Vec<String>,
2893    wasm_return: Option<String>,
2894    ret_store_cnt: usize,
2895    import_return_pointer_area_size: ArchitectureSize,
2896    import_return_pointer_area_align: Alignment,
2897
2898    /// State of what to generate for the `task.return` intrinsic in the case
2899    /// that this bindings generator is being used for an async export.
2900    ///
2901    /// This typically stays at `DeferredTaskReturn::None` except for the case
2902    /// of async exports where they'll fill this in after the `CallInterface`
2903    /// instruction. For some more information see the documentation on
2904    /// `DeferredTaskReturn`.
2905    deferred_task_return: DeferredTaskReturn,
2906
2907    /// Borrows observed during lifting an export, that will need to be dropped when the guest
2908    /// function exits.
2909    borrows: Vec<DroppableBorrow>,
2910
2911    /// Forward declarations for temporary storage of borrow copies.
2912    borrow_decls: wit_bindgen_core::Source,
2913}
2914
2915/// State associated with the generation of the `task.return` intrinsic function
2916/// with async exports.
2917enum DeferredTaskReturn {
2918    /// Default state, meaning that either bindings generation isn't happening
2919    /// for an async export or the async export is in the bindings generation
2920    /// mode before `CallInterface`.
2921    None,
2922
2923    /// An async export is having bindings generated and `CallInterface` has
2924    /// been seen. After that instruction the `deferred_task_return` field
2925    /// transitions to this state.
2926    ///
2927    /// This state is then present until the `AsyncTaskReturn` instruction is
2928    /// met at which point this changes to `Emitted` below.
2929    Generating {
2930        /// The previous contents of `self.src` just after the `CallInterface`
2931        /// had its code generator. This is effectively the bindings-generated
2932        /// contents of the export and this will get replaced back into
2933        /// `self.src` once the `AsyncTaskReturn` is generated.
2934        prev_src: wit_bindgen_core::Source,
2935    },
2936
2937    /// An `AsyncTaskReturn` has been seen and all state is now located here to
2938    /// be used for generating the `task.return` intrinsic.
2939    ///
2940    /// This state is only generated during `AsyncTaskReturn` and is used to
2941    /// record everything necessary to generate `task.return` meaning that the
2942    /// in-`FunctionBindgen` state is now "back to normal" where it's intended
2943    /// for the main function having bindings generated.
2944    Emitted {
2945        /// The name of the `task.return` intrinsic that should be imported.
2946        /// Note that this does not include the module.
2947        name: String,
2948        /// The wasm type of each parameter provided to the `task.return`
2949        /// intrinsic as well as the C expression necessary to produce this
2950        /// parameter. The type is used to declare the intrinsic and the C
2951        /// expression is used to call the intrinsic from the generated
2952        /// function.
2953        params: Vec<(WasmType, String)>,
2954        /// The body of the `task.return` intrinsic. This contains the bulk of
2955        /// the lowering code from a function's return value to the canonical
2956        /// ABI.
2957        body: wit_bindgen_core::Source,
2958    },
2959}
2960
2961impl<'a, 'b> FunctionBindgen<'a, 'b> {
2962    fn new(
2963        r#gen: &'a mut InterfaceGenerator<'b>,
2964        sig: CSig,
2965        func_to_call: &'a str,
2966    ) -> FunctionBindgen<'a, 'b> {
2967        let mut locals = Ns::default();
2968        for (_, name) in sig.params.iter() {
2969            locals.insert(name).unwrap();
2970        }
2971        FunctionBindgen {
2972            r#gen,
2973            sig,
2974            locals,
2975            src: Default::default(),
2976            func_to_call,
2977            block_storage: Vec::new(),
2978            blocks: Vec::new(),
2979            payloads: Vec::new(),
2980            params: Vec::new(),
2981            wasm_return: None,
2982            ret_store_cnt: 0,
2983            import_return_pointer_area_size: Default::default(),
2984            import_return_pointer_area_align: Default::default(),
2985            borrow_decls: Default::default(),
2986            borrows: Vec::new(),
2987            deferred_task_return: DeferredTaskReturn::None,
2988        }
2989    }
2990
2991    fn store_op(&mut self, op: &str, loc: &str) {
2992        self.src.push_str(loc);
2993        self.src.push_str(" = ");
2994        self.src.push_str(op);
2995        self.src.push_str(";\n");
2996    }
2997
2998    fn load(
2999        &mut self,
3000        ty: &str,
3001        offset: ArchitectureSize,
3002        operands: &[String],
3003        results: &mut Vec<String>,
3004    ) {
3005        results.push(format!(
3006            "*(({}*) ({} + {}))",
3007            ty,
3008            operands[0],
3009            offset.format(POINTER_SIZE_EXPRESSION)
3010        ));
3011    }
3012
3013    fn load_ext(
3014        &mut self,
3015        ty: &str,
3016        offset: ArchitectureSize,
3017        operands: &[String],
3018        results: &mut Vec<String>,
3019    ) {
3020        self.load(ty, offset, operands, results);
3021        let result = results.pop().unwrap();
3022        results.push(format!("(int32_t) {result}"));
3023    }
3024
3025    fn store(&mut self, ty: &str, offset: ArchitectureSize, operands: &[String]) {
3026        uwriteln!(
3027            self.src,
3028            "*(({}*)({} + {})) = {};",
3029            ty,
3030            operands[1],
3031            offset.format(POINTER_SIZE_EXPRESSION),
3032            operands[0]
3033        );
3034    }
3035
3036    fn store_in_retptr(&mut self, operand: &String) {
3037        self.store_op(
3038            operand,
3039            &format!("*{}", self.sig.retptrs[self.ret_store_cnt]),
3040        );
3041        self.ret_store_cnt = self.ret_store_cnt + 1;
3042    }
3043
3044    fn empty_return_value(&mut self) {
3045        // Empty types have no state, so we don't emit stores for them. But we
3046        // do need to keep track of which return variable we're looking at.
3047        self.ret_store_cnt = self.ret_store_cnt + 1;
3048    }
3049
3050    fn assert_no_droppable_borrows(&self, context: &str, ty: &Type) {
3051        if !self.r#gen.in_import
3052            && self.r#gen.autodrop_enabled()
3053            && self.r#gen.contains_droppable_borrow(ty)
3054        {
3055            panic!("Unable to autodrop borrows in `{context}` values, please disable autodrop")
3056        }
3057    }
3058}
3059
3060impl Bindgen for FunctionBindgen<'_, '_> {
3061    type Operand = String;
3062
3063    fn sizes(&self) -> &SizeAlign {
3064        &self.r#gen.r#gen.sizes
3065    }
3066
3067    fn push_block(&mut self) {
3068        let prev = mem::take(&mut self.src);
3069        self.block_storage.push(prev);
3070    }
3071
3072    fn finish_block(&mut self, operands: &mut Vec<String>) {
3073        let to_restore = self.block_storage.pop().unwrap();
3074        let src = mem::replace(&mut self.src, to_restore);
3075        self.blocks.push((src.into(), mem::take(operands)));
3076    }
3077
3078    fn return_pointer(&mut self, size: ArchitectureSize, align: Alignment) -> String {
3079        let ptr = self.locals.tmp("ptr");
3080
3081        // Use a stack-based return area for imports, because exports need
3082        // their return area to be live until the post-return call.
3083        if self.r#gen.in_import {
3084            self.import_return_pointer_area_size = self.import_return_pointer_area_size.max(size);
3085            self.import_return_pointer_area_align =
3086                self.import_return_pointer_area_align.max(align);
3087            uwriteln!(self.src, "uint8_t *{} = (uint8_t *) &ret_area;", ptr);
3088        } else {
3089            self.r#gen.r#gen.return_pointer_area_size =
3090                self.r#gen.r#gen.return_pointer_area_size.max(size);
3091            self.r#gen.r#gen.return_pointer_area_align =
3092                self.r#gen.r#gen.return_pointer_area_align.max(align);
3093            // Declare a statically-allocated return area.
3094            uwriteln!(self.src, "uint8_t *{} = (uint8_t *) &RET_AREA;", ptr);
3095        }
3096
3097        ptr
3098    }
3099
3100    fn is_list_canonical(&self, resolve: &Resolve, ty: &Type) -> bool {
3101        resolve.all_bits_valid(ty)
3102    }
3103
3104    fn emit(
3105        &mut self,
3106        resolve: &Resolve,
3107        inst: &Instruction<'_>,
3108        operands: &mut Vec<String>,
3109        results: &mut Vec<String>,
3110    ) {
3111        match inst {
3112            Instruction::GetArg { nth } => results.push(self.params[*nth].clone()),
3113            Instruction::I32Const { val } => results.push(val.to_string()),
3114            Instruction::ConstZero { tys } => {
3115                for _ in tys.iter() {
3116                    results.push("0".to_string());
3117                }
3118            }
3119
3120            // TODO: checked?
3121            Instruction::U8FromI32 => results.push(format!("(uint8_t) ({})", operands[0])),
3122            Instruction::S8FromI32 => results.push(format!("(int8_t) ({})", operands[0])),
3123            Instruction::U16FromI32 => results.push(format!("(uint16_t) ({})", operands[0])),
3124            Instruction::S16FromI32 => results.push(format!("(int16_t) ({})", operands[0])),
3125            Instruction::U32FromI32 => results.push(format!("(uint32_t) ({})", operands[0])),
3126            Instruction::S32FromI32 | Instruction::S64FromI64 => results.push(operands[0].clone()),
3127            Instruction::U64FromI64 => results.push(format!("(uint64_t) ({})", operands[0])),
3128
3129            Instruction::I32FromU8
3130            | Instruction::I32FromS8
3131            | Instruction::I32FromU16
3132            | Instruction::I32FromS16
3133            | Instruction::I32FromU32 => {
3134                results.push(format!("(int32_t) ({})", operands[0]));
3135            }
3136            Instruction::I32FromS32 | Instruction::I64FromS64 => results.push(operands[0].clone()),
3137            Instruction::I64FromU64 => {
3138                results.push(format!("(int64_t) ({})", operands[0]));
3139            }
3140
3141            // f32/f64 have the same representation in the import type and in C,
3142            // so no conversions necessary.
3143            Instruction::CoreF32FromF32
3144            | Instruction::CoreF64FromF64
3145            | Instruction::F32FromCoreF32
3146            | Instruction::F64FromCoreF64 => {
3147                results.push(operands[0].clone());
3148            }
3149
3150            // TODO: checked
3151            Instruction::CharFromI32 => {
3152                results.push(format!("(uint32_t) ({})", operands[0]));
3153            }
3154            Instruction::I32FromChar => {
3155                results.push(format!("(int32_t) ({})", operands[0]));
3156            }
3157
3158            Instruction::Bitcasts { casts } => {
3159                for (cast, op) in casts.iter().zip(operands) {
3160                    let op = self.r#gen.r#gen.perform_cast(op, cast);
3161                    results.push(op);
3162                }
3163            }
3164
3165            Instruction::BoolFromI32 | Instruction::I32FromBool => {
3166                results.push(operands[0].clone());
3167            }
3168
3169            Instruction::RecordLower { record, .. } => {
3170                let op = &operands[0];
3171                for f in record.fields.iter() {
3172                    results.push(format!("({}).{}", op, to_c_ident(&f.name)));
3173                }
3174            }
3175            Instruction::RecordLift { ty, record, .. } => {
3176                let name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3177                let mut result = format!("({name}) {{\n");
3178                for (field, op) in record.fields.iter().zip(operands.iter()) {
3179                    let field_ty = self.r#gen.r#gen.type_name(&field.ty);
3180                    uwriteln!(result, "({}) {},", field_ty, op);
3181                }
3182                result.push_str("}");
3183                results.push(result);
3184            }
3185
3186            Instruction::TupleLower { tuple, .. } => {
3187                let op = &operands[0];
3188                for i in 0..tuple.types.len() {
3189                    results.push(format!("({op}).f{i}"));
3190                }
3191            }
3192            Instruction::TupleLift { ty, tuple, .. } => {
3193                let name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3194                let mut result = format!("({name}) {{\n");
3195                for (ty, op) in tuple.types.iter().zip(operands.iter()) {
3196                    let ty = self.r#gen.r#gen.type_name(&ty);
3197                    uwriteln!(result, "({}) {},", ty, op);
3198                }
3199                result.push_str("}");
3200                results.push(result);
3201            }
3202
3203            Instruction::HandleLower { .. } => {
3204                let op = &operands[0];
3205                results.push(format!("({op}).__handle"))
3206            }
3207
3208            Instruction::HandleLift { handle, ty, .. } => match handle {
3209                Handle::Borrow(resource)
3210                    if matches!(
3211                        self.r#gen.r#gen.resources[&dealias(resolve, *resource)].direction,
3212                        Direction::Export
3213                    ) =>
3214                {
3215                    // Here we've received a borrow of a resource which we've exported ourselves, so we can treat
3216                    // it as a raw pointer rather than an opaque handle.
3217                    let op = &operands[0];
3218                    let name = self
3219                        .r#gen
3220                        .r#gen
3221                        .type_name(&Type::Id(dealias(resolve, *resource)));
3222                    results.push(format!("(({name}*) {op})"))
3223                }
3224                _ => {
3225                    let op = &operands[0];
3226                    let name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3227                    results.push(format!("({name}) {{ {op} }}"));
3228
3229                    if let Handle::Borrow(id) = handle {
3230                        if !self.r#gen.in_import && self.r#gen.autodrop_enabled() {
3231                            // Here we've received a borrow of an imported resource, which is the
3232                            // kind we'll need to drop when the exported function is returning.
3233                            let ty = dealias(self.r#gen.resolve, *id);
3234
3235                            let name = self.locals.tmp("borrow");
3236                            uwriteln!(self.borrow_decls, "int32_t {name} = 0;");
3237                            uwriteln!(self.src, "{name} = {op};");
3238
3239                            self.borrows.push(DroppableBorrow { name, ty });
3240                        }
3241                    }
3242                }
3243            },
3244
3245            // TODO: checked
3246            Instruction::FlagsLower { flags, ty, .. } => match flags_repr(flags) {
3247                Int::U8 | Int::U16 | Int::U32 => {
3248                    results.push(operands.pop().unwrap());
3249                }
3250                Int::U64 => {
3251                    let name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3252                    let tmp = self.locals.tmp("flags");
3253                    uwriteln!(self.src, "{name} {tmp} = {};", operands[0]);
3254                    results.push(format!("{tmp} & 0xffffffff"));
3255                    results.push(format!("({tmp} >> 32) & 0xffffffff"));
3256                }
3257            },
3258
3259            Instruction::FlagsLift { flags, ty, .. } => match flags_repr(flags) {
3260                Int::U8 | Int::U16 | Int::U32 => {
3261                    results.push(operands.pop().unwrap());
3262                }
3263                Int::U64 => {
3264                    let name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3265                    let op0 = &operands[0];
3266                    let op1 = &operands[1];
3267                    results.push(format!("(({name}) ({op0})) | ((({name}) ({op1})) << 32)"));
3268                }
3269            },
3270
3271            Instruction::VariantPayloadName => {
3272                let name = self.locals.tmp("payload");
3273                results.push(format!("*{name}"));
3274                self.payloads.push(name);
3275            }
3276
3277            Instruction::VariantLower {
3278                variant,
3279                results: result_types,
3280                ..
3281            } => {
3282                let blocks = self
3283                    .blocks
3284                    .drain(self.blocks.len() - variant.cases.len()..)
3285                    .collect::<Vec<_>>();
3286                let payloads = self
3287                    .payloads
3288                    .drain(self.payloads.len() - variant.cases.len()..)
3289                    .collect::<Vec<_>>();
3290
3291                let mut variant_results = Vec::with_capacity(result_types.len());
3292                for ty in result_types.iter() {
3293                    let name = self.locals.tmp("variant");
3294                    results.push(name.clone());
3295                    self.src.push_str(wasm_type(*ty));
3296                    self.src.push_str(" ");
3297                    self.src.push_str(&name);
3298                    self.src.push_str(";\n");
3299                    variant_results.push(name);
3300                }
3301
3302                let expr_to_match = format!("({}).tag", operands[0]);
3303
3304                uwriteln!(self.src, "switch ((int32_t) {}) {{", expr_to_match);
3305                for (i, ((case, (block, block_results)), payload)) in
3306                    variant.cases.iter().zip(blocks).zip(payloads).enumerate()
3307                {
3308                    uwriteln!(self.src, "case {}: {{", i);
3309                    if let Some(ty) = case.ty.as_ref() {
3310                        let ty = self.r#gen.r#gen.type_name(ty);
3311                        uwrite!(
3312                            self.src,
3313                            "const {} *{} = &({}).val",
3314                            ty,
3315                            payload,
3316                            operands[0],
3317                        );
3318                        self.src.push_str(".");
3319                        self.src.push_str(&to_c_ident(&case.name));
3320                        self.src.push_str(";\n");
3321                    }
3322                    self.src.push_str(&block);
3323
3324                    for (name, result) in variant_results.iter().zip(&block_results) {
3325                        uwriteln!(self.src, "{} = {};", name, result);
3326                    }
3327                    self.src.push_str("break;\n}\n");
3328                }
3329                self.src.push_str("}\n");
3330            }
3331
3332            Instruction::VariantLift { variant, ty, .. } => {
3333                let blocks = self
3334                    .blocks
3335                    .drain(self.blocks.len() - variant.cases.len()..)
3336                    .collect::<Vec<_>>();
3337
3338                let ty = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3339                let result = self.locals.tmp("variant");
3340                uwriteln!(self.src, "{} {};", ty, result);
3341                uwriteln!(self.src, "{}.tag = {};", result, operands[0]);
3342                uwriteln!(self.src, "switch ((int32_t) {}.tag) {{", result);
3343                for (i, (case, (block, block_results))) in
3344                    variant.cases.iter().zip(blocks).enumerate()
3345                {
3346                    uwriteln!(self.src, "case {}: {{", i);
3347                    self.src.push_str(&block);
3348                    assert!(block_results.len() == (case.ty.is_some() as usize));
3349
3350                    if let Some(_) = case.ty.as_ref() {
3351                        let mut dst = format!("{result}.val");
3352                        dst.push_str(".");
3353                        dst.push_str(&to_c_ident(&case.name));
3354                        self.store_op(&block_results[0], &dst);
3355                    }
3356                    self.src.push_str("break;\n}\n");
3357                }
3358                self.src.push_str("}\n");
3359                results.push(result);
3360            }
3361
3362            Instruction::OptionLower {
3363                results: result_types,
3364                payload,
3365                ..
3366            } => {
3367                let (mut some, some_results) = self.blocks.pop().unwrap();
3368                let (mut none, none_results) = self.blocks.pop().unwrap();
3369                let some_payload = self.payloads.pop().unwrap();
3370                let _none_payload = self.payloads.pop().unwrap();
3371
3372                for (i, ty) in result_types.iter().enumerate() {
3373                    let name = self.locals.tmp("option");
3374                    results.push(name.clone());
3375                    self.src.push_str(wasm_type(*ty));
3376                    self.src.push_str(" ");
3377                    self.src.push_str(&name);
3378                    self.src.push_str(";\n");
3379                    let some_result = &some_results[i];
3380                    uwriteln!(some, "{name} = {some_result};");
3381                    let none_result = &none_results[i];
3382                    uwriteln!(none, "{name} = {none_result};");
3383                }
3384
3385                let op0 = &operands[0];
3386                let ty = self.r#gen.r#gen.type_name(payload);
3387                let bind_some = format!("const {ty} *{some_payload} = &({op0}).val;");
3388
3389                uwrite!(
3390                    self.src,
3391                    "\
3392                    if (({op0}).is_some) {{
3393                        {bind_some}
3394                        {some}}} else {{
3395                        {none}}}
3396                    "
3397                );
3398            }
3399
3400            Instruction::OptionLift { ty, .. } => {
3401                let (mut some, some_results) = self.blocks.pop().unwrap();
3402                let (mut none, none_results) = self.blocks.pop().unwrap();
3403                assert!(none_results.len() == 0);
3404                assert!(some_results.len() == 1);
3405                let some_result = &some_results[0];
3406
3407                let ty = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3408                let result = self.locals.tmp("option");
3409                uwriteln!(self.src, "{ty} {result};");
3410                let op0 = &operands[0];
3411                let set_some = format!("{result}.val = {some_result};\n");
3412                if none.len() > 0 {
3413                    none.push('\n');
3414                }
3415                if some.len() > 0 {
3416                    some.push('\n');
3417                }
3418                uwrite!(
3419                    self.src,
3420                    "switch ({op0}) {{
3421                        case 0: {{
3422                            {result}.is_some = false;
3423                            {none}\
3424                            break;
3425                        }}
3426                        case 1: {{
3427                            {result}.is_some = true;
3428                            {some}\
3429                            {set_some}\
3430                            break;
3431                        }}
3432                    }}\n"
3433                );
3434                results.push(result);
3435            }
3436
3437            Instruction::ResultLower {
3438                results: result_types,
3439                result,
3440                ..
3441            } => {
3442                let (mut err, err_results) = self.blocks.pop().unwrap();
3443                let (mut ok, ok_results) = self.blocks.pop().unwrap();
3444                let err_payload = self.payloads.pop().unwrap();
3445                let ok_payload = self.payloads.pop().unwrap();
3446
3447                for (i, ty) in result_types.iter().enumerate() {
3448                    let name = self.locals.tmp("result");
3449                    results.push(name.clone());
3450                    self.src.push_str(wasm_type(*ty));
3451                    self.src.push_str(" ");
3452                    self.src.push_str(&name);
3453                    self.src.push_str(";\n");
3454                    let ok_result = &ok_results[i];
3455                    uwriteln!(ok, "{name} = {ok_result};");
3456                    let err_result = &err_results[i];
3457                    uwriteln!(err, "{name} = {err_result};");
3458                }
3459
3460                let op0 = &operands[0];
3461                let bind_ok = if let Some(ok) = result.ok.as_ref() {
3462                    let ok_ty = self.r#gen.r#gen.type_name(ok);
3463                    format!("const {ok_ty} *{ok_payload} = &({op0}).val.ok;")
3464                } else {
3465                    String::new()
3466                };
3467                let bind_err = if let Some(err) = result.err.as_ref() {
3468                    let err_ty = self.r#gen.r#gen.type_name(err);
3469                    format!("const {err_ty} *{err_payload} = &({op0}).val.err;")
3470                } else {
3471                    String::new()
3472                };
3473                uwrite!(
3474                    self.src,
3475                    "\
3476                    if (({op0}).is_err) {{
3477                        {bind_err}\
3478                        {err}\
3479                    }} else {{
3480                        {bind_ok}\
3481                        {ok}\
3482                    }}
3483                    "
3484                );
3485            }
3486
3487            Instruction::ResultLift { result, ty, .. } => {
3488                let (mut err, err_results) = self.blocks.pop().unwrap();
3489                assert!(err_results.len() == (result.err.is_some() as usize));
3490                let (mut ok, ok_results) = self.blocks.pop().unwrap();
3491                assert!(ok_results.len() == (result.ok.is_some() as usize));
3492
3493                if err.len() > 0 {
3494                    err.push_str("\n");
3495                }
3496                if ok.len() > 0 {
3497                    ok.push_str("\n");
3498                }
3499
3500                let result_tmp = self.locals.tmp("result");
3501                let set_ok = if let Some(_) = result.ok.as_ref() {
3502                    let ok_result = &ok_results[0];
3503                    format!("{result_tmp}.val.ok = {ok_result};\n")
3504                } else {
3505                    String::new()
3506                };
3507                let set_err = if let Some(_) = result.err.as_ref() {
3508                    let err_result = &err_results[0];
3509                    format!("{result_tmp}.val.err = {err_result};\n")
3510                } else {
3511                    String::new()
3512                };
3513
3514                let ty = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3515                uwriteln!(self.src, "{ty} {result_tmp};");
3516                let op0 = &operands[0];
3517                uwriteln!(
3518                    self.src,
3519                    "switch ({op0}) {{
3520                        case 0: {{
3521                            {result_tmp}.is_err = false;
3522                            {ok}\
3523                            {set_ok}\
3524                            break;
3525                        }}
3526                        case 1: {{
3527                            {result_tmp}.is_err = true;
3528                            {err}\
3529                            {set_err}\
3530                            break;
3531                        }}
3532                    }}"
3533                );
3534                results.push(result_tmp);
3535            }
3536
3537            Instruction::EnumLower { .. } => results.push(format!("(int32_t) {}", operands[0])),
3538            Instruction::EnumLift { .. } => results.push(operands.pop().unwrap()),
3539
3540            Instruction::ListCanonLower { .. } | Instruction::StringLower { .. } => {
3541                results.push(format!("(uint8_t *) ({}).ptr", operands[0]));
3542                results.push(format!("({}).len", operands[0]));
3543            }
3544            Instruction::ListCanonLift { element, ty, .. } => {
3545                self.assert_no_droppable_borrows("list", &Type::Id(*ty));
3546
3547                let list_name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3548                let elem_name = self.r#gen.r#gen.type_name(element);
3549                results.push(format!(
3550                    "({}) {{ ({}*)({}), ({}) }}",
3551                    list_name, elem_name, operands[0], operands[1]
3552                ));
3553            }
3554            Instruction::StringLift { .. } => {
3555                let list_name = self.r#gen.r#gen.type_name(&Type::String);
3556                results.push(format!(
3557                    "({}) {{ ({}*)({}), ({}) }}",
3558                    list_name,
3559                    self.r#gen.r#gen.char_type(),
3560                    operands[0],
3561                    operands[1]
3562                ));
3563            }
3564
3565            Instruction::ListLower { .. } => {
3566                let _body = self.blocks.pop().unwrap();
3567                results.push(format!("(uint8_t *) ({}).ptr", operands[0]));
3568                results.push(format!("({}).len", operands[0]));
3569            }
3570
3571            Instruction::ListLift { element, ty, .. } => {
3572                self.assert_no_droppable_borrows("list", &Type::Id(*ty));
3573
3574                let _body = self.blocks.pop().unwrap();
3575                let list_name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3576                let elem_name = self.r#gen.r#gen.type_name(element);
3577                results.push(format!(
3578                    "({}) {{ ({}*)({}), ({}) }}",
3579                    list_name, elem_name, operands[0], operands[1]
3580                ));
3581            }
3582            Instruction::IterElem { .. } => results.push("e".to_string()),
3583            Instruction::IterBasePointer => results.push("base".to_string()),
3584
3585            Instruction::CallWasm { sig, .. } => {
3586                match sig.results.len() {
3587                    0 => {}
3588                    1 => {
3589                        self.src.push_str(wasm_type(sig.results[0]));
3590                        let ret = self.locals.tmp("ret");
3591                        self.wasm_return = Some(ret.clone());
3592                        uwrite!(self.src, " {} = ", ret);
3593                        results.push(ret);
3594                    }
3595                    _ => unimplemented!(),
3596                }
3597                self.src.push_str(self.func_to_call);
3598                self.src.push_str("(");
3599                for (i, op) in operands.iter().enumerate() {
3600                    if i > 0 {
3601                        self.src.push_str(", ");
3602                    }
3603                    self.src.push_str(op);
3604                }
3605                self.src.push_str(");\n");
3606            }
3607
3608            Instruction::CallInterface { func, async_ } => {
3609                let mut args = String::new();
3610                for (i, (op, (byref, _))) in operands.iter().zip(&self.sig.params).enumerate() {
3611                    if i > 0 {
3612                        args.push_str(", ");
3613                    }
3614                    let ty = &func.params[i].1;
3615                    if *byref {
3616                        let name = self.locals.tmp("arg");
3617                        let ty = self.r#gen.r#gen.type_name(ty);
3618                        uwriteln!(self.src, "{} {} = {};", ty, name, op);
3619                        args.push_str("&");
3620                        args.push_str(&name);
3621                    } else {
3622                        if !self.r#gen.in_import {
3623                            if let Type::Id(id) = ty {
3624                                if let TypeDefKind::Option(_) = &self.r#gen.resolve.types[*id].kind
3625                                {
3626                                    uwrite!(args, "{op}.is_some ? &({op}.val) : NULL");
3627                                    continue;
3628                                }
3629                            }
3630                        }
3631                        args.push_str(op);
3632                    }
3633                }
3634                if *async_ {
3635                    let ret = self.locals.tmp("ret");
3636                    let snake = self.r#gen.r#gen.world.to_snake_case();
3637                    uwriteln!(
3638                        self.src,
3639                        "{snake}_callback_code_t {ret} = {}({args});",
3640                        self.sig.name,
3641                    );
3642                    uwriteln!(self.src, "return {ret};");
3643                    if func.result.is_some() {
3644                        results.push("ret".to_string());
3645                    }
3646                    assert!(matches!(
3647                        self.deferred_task_return,
3648                        DeferredTaskReturn::None
3649                    ));
3650                    self.deferred_task_return = DeferredTaskReturn::Generating {
3651                        prev_src: mem::take(&mut self.src),
3652                    };
3653                    return;
3654                }
3655                match &self.sig.ret.scalar {
3656                    None => {
3657                        let mut retptrs = Vec::new();
3658                        for ty in self.sig.ret.retptrs.iter() {
3659                            let name = self.locals.tmp("ret");
3660                            let ty = self.r#gen.r#gen.type_name(ty);
3661                            uwriteln!(self.src, "{} {};", ty, name);
3662                            if args.len() > 0 {
3663                                args.push_str(", ");
3664                            }
3665                            args.push_str("&");
3666                            args.push_str(&name);
3667                            retptrs.push(name);
3668                        }
3669                        uwriteln!(self.src, "{}({});", self.sig.name, args);
3670                        results.extend(retptrs);
3671                    }
3672                    Some(Scalar::Void) => {
3673                        uwriteln!(self.src, "{}({});", self.sig.name, args);
3674                    }
3675                    Some(Scalar::Type(_)) => {
3676                        let ret = self.locals.tmp("ret");
3677                        let ty = func.result.unwrap();
3678                        let ty = self.r#gen.r#gen.type_name(&ty);
3679                        uwriteln!(self.src, "{} {} = {}({});", ty, ret, self.sig.name, args);
3680                        results.push(ret);
3681                    }
3682                    Some(Scalar::OptionBool(ty)) => {
3683                        let ret = self.locals.tmp("ret");
3684                        let val = self.locals.tmp("val");
3685                        if args.len() > 0 {
3686                            args.push_str(", ");
3687                        }
3688                        args.push_str("&");
3689                        args.push_str(&val);
3690                        let payload_ty = self.r#gen.r#gen.type_name(ty);
3691                        uwriteln!(self.src, "{} {};", payload_ty, val);
3692                        uwriteln!(self.src, "bool {} = {}({});", ret, self.sig.name, args);
3693                        let ty = func.result.unwrap();
3694                        let option_ty = self.r#gen.r#gen.type_name(&ty);
3695                        let option_ret = self.locals.tmp("ret");
3696                        uwrite!(
3697                            self.src,
3698                            "
3699                                {option_ty} {option_ret};
3700                                {option_ret}.is_some = {ret};
3701                                {option_ret}.val = {val};
3702                            ",
3703                        );
3704                        results.push(option_ret);
3705                    }
3706                    Some(Scalar::ResultBool(ok, err)) => {
3707                        let ty = &func.result.unwrap();
3708                        let result_ty = self.r#gen.r#gen.type_name(ty);
3709                        let ret = self.locals.tmp("ret");
3710                        let mut ret_iter = self.sig.ret.retptrs.iter();
3711                        uwriteln!(self.src, "{result_ty} {ret};");
3712                        let ok_name = if ok.is_some() {
3713                            if let Some(ty) = ret_iter.next() {
3714                                let val = self.locals.tmp("ok");
3715                                if args.len() > 0 {
3716                                    uwrite!(args, ", ");
3717                                }
3718                                uwrite!(args, "&{val}");
3719                                let ty = self.r#gen.r#gen.type_name(ty);
3720                                uwriteln!(self.src, "{} {};", ty, val);
3721                                Some(val)
3722                            } else {
3723                                None
3724                            }
3725                        } else {
3726                            None
3727                        };
3728                        let err_name = if let Some(ty) = ret_iter.next() {
3729                            let val = self.locals.tmp("err");
3730                            if args.len() > 0 {
3731                                uwrite!(args, ", ")
3732                            }
3733                            uwrite!(args, "&{val}");
3734                            let ty = self.r#gen.r#gen.type_name(ty);
3735                            uwriteln!(self.src, "{} {};", ty, val);
3736                            Some(val)
3737                        } else {
3738                            None
3739                        };
3740                        assert!(ret_iter.next().is_none());
3741                        uwrite!(self.src, "");
3742                        uwriteln!(self.src, "{ret}.is_err = !{}({args});", self.sig.name);
3743                        if err.is_some() {
3744                            if let Some(err_name) = err_name {
3745                                uwriteln!(
3746                                    self.src,
3747                                    "if ({ret}.is_err) {{
3748                                        {ret}.val.err = {err_name};
3749                                    }}",
3750                                );
3751                            }
3752                        }
3753                        if ok.is_some() {
3754                            if let Some(ok_name) = ok_name {
3755                                uwriteln!(
3756                                    self.src,
3757                                    "if (!{ret}.is_err) {{
3758                                        {ret}.val.ok = {ok_name};
3759                                    }}"
3760                                );
3761                            } else {
3762                                uwrite!(self.src, "\n");
3763                            }
3764                        }
3765                        results.push(ret);
3766                    }
3767                }
3768            }
3769            Instruction::Return { .. } if self.r#gen.in_import => match self.sig.ret.scalar {
3770                None => {
3771                    for op in operands.iter() {
3772                        self.store_in_retptr(op);
3773                    }
3774                }
3775                Some(Scalar::Void) => {
3776                    assert!(operands.is_empty());
3777                }
3778                Some(Scalar::Type(_)) => {
3779                    assert_eq!(operands.len(), 1);
3780                    self.src.push_str("return ");
3781                    self.src.push_str(&operands[0]);
3782                    self.src.push_str(";\n");
3783                }
3784                Some(Scalar::OptionBool(_)) => {
3785                    assert_eq!(operands.len(), 1);
3786                    let variant = &operands[0];
3787                    self.store_in_retptr(&format!("{variant}.val"));
3788                    self.src.push_str("return ");
3789                    self.src.push_str(&variant);
3790                    self.src.push_str(".is_some;\n");
3791                }
3792                Some(Scalar::ResultBool(ok, err)) => {
3793                    assert_eq!(operands.len(), 1);
3794                    let variant = &operands[0];
3795                    assert!(self.sig.retptrs.len() <= 2);
3796                    uwriteln!(self.src, "if (!{}.is_err) {{", variant);
3797                    if ok.is_some() {
3798                        if ok.is_some() {
3799                            self.store_in_retptr(&format!("{variant}.val.ok"));
3800                        } else {
3801                            self.empty_return_value();
3802                        }
3803                    }
3804                    uwriteln!(
3805                        self.src,
3806                        "   return 1;
3807                            }} else {{"
3808                    );
3809                    if err.is_some() {
3810                        if err.is_some() {
3811                            self.store_in_retptr(&format!("{variant}.val.err"));
3812                        } else {
3813                            self.empty_return_value();
3814                        }
3815                    }
3816                    uwriteln!(
3817                        self.src,
3818                        "   return 0;
3819                            }}"
3820                    );
3821                    assert_eq!(self.ret_store_cnt, self.sig.retptrs.len());
3822                }
3823            },
3824            Instruction::Return { amt, .. } => {
3825                // Emit all temporary borrow decls
3826                let src = std::mem::replace(&mut self.src, std::mem::take(&mut self.borrow_decls));
3827                self.src.append_src(&src);
3828
3829                for DroppableBorrow { name, ty } in self.borrows.iter() {
3830                    let drop_fn = self.r#gen.r#gen.resources[ty].drop_fn.as_str();
3831                    uwriteln!(self.src, "if ({name} != 0) {{");
3832                    uwriteln!(self.src, "  {drop_fn}({name});");
3833                    uwriteln!(self.src, "}}");
3834                }
3835
3836                assert!(*amt <= 1);
3837                if *amt == 1 {
3838                    uwriteln!(self.src, "return {};", operands[0]);
3839                }
3840            }
3841
3842            Instruction::I32Load { offset } => self.load("int32_t", *offset, operands, results),
3843            Instruction::I64Load { offset } => self.load("int64_t", *offset, operands, results),
3844            Instruction::F32Load { offset } => self.load("float", *offset, operands, results),
3845            Instruction::F64Load { offset } => self.load("double", *offset, operands, results),
3846            Instruction::PointerLoad { offset } => {
3847                self.load("uint8_t *", *offset, operands, results)
3848            }
3849            Instruction::LengthLoad { offset } => self.load("size_t", *offset, operands, results),
3850            Instruction::I32Store { offset } => self.store("int32_t", *offset, operands),
3851            Instruction::I64Store { offset } => self.store("int64_t", *offset, operands),
3852            Instruction::F32Store { offset } => self.store("float", *offset, operands),
3853            Instruction::F64Store { offset } => self.store("double", *offset, operands),
3854            Instruction::I32Store8 { offset } => self.store("int8_t", *offset, operands),
3855            Instruction::I32Store16 { offset } => self.store("int16_t", *offset, operands),
3856            Instruction::PointerStore { offset } => self.store("uint8_t *", *offset, operands),
3857            Instruction::LengthStore { offset } => self.store("size_t", *offset, operands),
3858
3859            Instruction::I32Load8U { offset } => {
3860                self.load_ext("uint8_t", *offset, operands, results)
3861            }
3862            Instruction::I32Load8S { offset } => {
3863                self.load_ext("int8_t", *offset, operands, results)
3864            }
3865            Instruction::I32Load16U { offset } => {
3866                self.load_ext("uint16_t", *offset, operands, results)
3867            }
3868            Instruction::I32Load16S { offset } => {
3869                self.load_ext("int16_t", *offset, operands, results)
3870            }
3871
3872            Instruction::GuestDeallocate { .. } => {
3873                uwriteln!(self.src, "free({});", operands[0]);
3874            }
3875            Instruction::GuestDeallocateString => {
3876                uwriteln!(self.src, "if (({}) > 0) {{", operands[1]);
3877                uwriteln!(self.src, "free({});", operands[0]);
3878                uwriteln!(self.src, "}}");
3879            }
3880            Instruction::GuestDeallocateVariant { blocks } => {
3881                let blocks = self
3882                    .blocks
3883                    .drain(self.blocks.len() - blocks..)
3884                    .collect::<Vec<_>>();
3885
3886                uwriteln!(self.src, "switch ((int32_t) {}) {{", operands[0]);
3887                for (i, (block, results)) in blocks.into_iter().enumerate() {
3888                    assert!(results.is_empty());
3889                    uwriteln!(self.src, "case {}: {{", i);
3890                    self.src.push_str(&block);
3891                    self.src.push_str("break;\n}\n");
3892                }
3893                self.src.push_str("}\n");
3894            }
3895            Instruction::GuestDeallocateList { element } => {
3896                let (body, results) = self.blocks.pop().unwrap();
3897                assert!(results.is_empty());
3898                let len = self.locals.tmp("len");
3899                uwriteln!(self.src, "size_t {len} = {};", operands[1]);
3900                uwriteln!(self.src, "if ({len} > 0) {{");
3901                let ptr = self.locals.tmp("ptr");
3902                uwriteln!(self.src, "uint8_t *{ptr} = {};", operands[0]);
3903                let i = self.locals.tmp("i");
3904                uwriteln!(self.src, "for (size_t {i} = 0; {i} < {len}; {i}++) {{");
3905                let size = self.r#gen.r#gen.sizes.size(element);
3906                uwriteln!(
3907                    self.src,
3908                    "uint8_t *base = {ptr} + {i} * {};",
3909                    size.format(POINTER_SIZE_EXPRESSION)
3910                );
3911                uwriteln!(self.src, "(void) base;");
3912                uwrite!(self.src, "{body}");
3913                uwriteln!(self.src, "}}");
3914                uwriteln!(self.src, "free({ptr});");
3915                uwriteln!(self.src, "}}");
3916            }
3917
3918            Instruction::Flush { amt } => {
3919                results.extend(operands.iter().take(*amt).cloned());
3920            }
3921
3922            Instruction::AsyncTaskReturn { name, params } => {
3923                let body = match &mut self.deferred_task_return {
3924                    DeferredTaskReturn::Generating { prev_src } => {
3925                        mem::swap(&mut self.src, prev_src);
3926                        mem::take(prev_src)
3927                    }
3928                    _ => unreachable!(),
3929                };
3930                assert_eq!(params.len(), operands.len());
3931                self.deferred_task_return = DeferredTaskReturn::Emitted {
3932                    name: name.to_string(),
3933                    body,
3934                    params: params
3935                        .iter()
3936                        .zip(operands)
3937                        .map(|(a, b)| (*a, b.clone()))
3938                        .collect(),
3939                };
3940            }
3941
3942            Instruction::FutureLift { .. } => {
3943                results.push(format!("((uint32_t) {})", operands[0]));
3944            }
3945            Instruction::FutureLower { .. } => {
3946                results.push(format!("((int32_t) {})", operands[0]));
3947            }
3948            Instruction::StreamLift { .. } => {
3949                results.push(format!("((uint32_t) {})", operands[0]));
3950            }
3951            Instruction::StreamLower { .. } => {
3952                results.push(format!("((int32_t) {})", operands[0]));
3953            }
3954
3955            i => unimplemented!("{:?}", i),
3956        }
3957    }
3958}
3959
3960#[derive(Default, Clone, Copy)]
3961enum SourceType {
3962    #[default]
3963    HDefs,
3964    HFns,
3965    // HHelpers,
3966    // CDefs,
3967    // CFns,
3968    // CHelpers,
3969    // CAdapters,
3970}
3971
3972#[derive(Default)]
3973struct Source {
3974    h_defs: wit_bindgen_core::Source,
3975    h_fns: wit_bindgen_core::Source,
3976    h_helpers: wit_bindgen_core::Source,
3977    h_async: wit_bindgen_core::Source,
3978    c_defs: wit_bindgen_core::Source,
3979    c_fns: wit_bindgen_core::Source,
3980    c_helpers: wit_bindgen_core::Source,
3981    c_adapters: wit_bindgen_core::Source,
3982    c_async: wit_bindgen_core::Source,
3983}
3984
3985impl Source {
3986    fn src(&mut self, stype: SourceType) -> &mut wit_bindgen_core::Source {
3987        match stype {
3988            SourceType::HDefs => &mut self.h_defs,
3989            SourceType::HFns => &mut self.h_fns,
3990        }
3991    }
3992    fn append(&mut self, append_src: &Source) {
3993        self.h_defs.push_str(&append_src.h_defs);
3994        self.h_fns.push_str(&append_src.h_fns);
3995        self.h_helpers.push_str(&append_src.h_helpers);
3996        self.h_async.push_str(&append_src.h_async);
3997        self.c_defs.push_str(&append_src.c_defs);
3998        self.c_fns.push_str(&append_src.c_fns);
3999        self.c_helpers.push_str(&append_src.c_helpers);
4000        self.c_adapters.push_str(&append_src.c_adapters);
4001        self.c_async.push_str(&append_src.c_async);
4002    }
4003    fn h_defs(&mut self, s: &str) {
4004        self.h_defs.push_str(s);
4005    }
4006    fn h_fns(&mut self, s: &str) {
4007        self.h_fns.push_str(s);
4008    }
4009    fn h_helpers(&mut self, s: &str) {
4010        self.h_helpers.push_str(s);
4011    }
4012    fn c_fns(&mut self, s: &str) {
4013        self.c_fns.push_str(s);
4014    }
4015    fn c_helpers(&mut self, s: &str) {
4016        self.c_helpers.push_str(s);
4017    }
4018    fn c_adapters(&mut self, s: &str) {
4019        self.c_adapters.push_str(s);
4020    }
4021}
4022
4023pub fn wasm_type(ty: WasmType) -> &'static str {
4024    match ty {
4025        WasmType::I32 => "int32_t",
4026        WasmType::I64 => "int64_t",
4027        WasmType::F32 => "float",
4028        WasmType::F64 => "double",
4029        WasmType::Pointer => "uint8_t *",
4030        WasmType::PointerOrI64 => "int64_t",
4031        WasmType::Length => "size_t",
4032    }
4033}
4034
4035pub fn int_repr(ty: Int) -> &'static str {
4036    match ty {
4037        Int::U8 => "uint8_t",
4038        Int::U16 => "uint16_t",
4039        Int::U32 => "uint32_t",
4040        Int::U64 => "uint64_t",
4041    }
4042}
4043
4044pub fn flags_repr(f: &Flags) -> Int {
4045    match f.repr() {
4046        FlagsRepr::U8 => Int::U8,
4047        FlagsRepr::U16 => Int::U16,
4048        FlagsRepr::U32(1) => Int::U32,
4049        FlagsRepr::U32(2) => Int::U64,
4050        repr => panic!("unimplemented flags {repr:?}"),
4051    }
4052}
4053
4054pub fn is_arg_by_pointer(resolve: &Resolve, ty: &Type) -> bool {
4055    match ty {
4056        Type::Id(id) => match resolve.types[*id].kind {
4057            TypeDefKind::Type(t) => is_arg_by_pointer(resolve, &t),
4058            TypeDefKind::Variant(_) => true,
4059            TypeDefKind::Option(_) => true,
4060            TypeDefKind::Result(_) => true,
4061            TypeDefKind::Enum(_) => false,
4062            TypeDefKind::Flags(_) => false,
4063            TypeDefKind::Handle(_) => false,
4064            TypeDefKind::Tuple(_) | TypeDefKind::Record(_) | TypeDefKind::List(_) => true,
4065            TypeDefKind::Future(_) => false,
4066            TypeDefKind::Stream(_) => false,
4067            TypeDefKind::Resource => todo!("is_arg_by_pointer for resource"),
4068            TypeDefKind::Unknown => unreachable!(),
4069            TypeDefKind::FixedSizeList(..) => todo!(),
4070            TypeDefKind::Map(..) => todo!(),
4071        },
4072        Type::String => true,
4073        _ => false,
4074    }
4075}
4076
4077pub fn to_c_ident(name: &str) -> String {
4078    match name {
4079        // Escape C and C++ keywords.
4080        // Source: https://en.cppreference.com/w/cpp/keyword
4081        "alignas" => "alignas_".into(),
4082        "alignof" => "alignof_".into(),
4083        "and" => "and_".into(),
4084        "and_eq" => "and_eq_".into(),
4085        "asm" => "asm_".into(),
4086        "atomic_cancel" => "atomic_cancel_".into(),
4087        "atomic_commit" => "atomic_commit_".into(),
4088        "atomic_noexcept" => "atomic_noexcept_".into(),
4089        "auto" => "auto_".into(),
4090        "bitand" => "bitand_".into(),
4091        "bitor" => "bitor_".into(),
4092        "bool" => "bool_".into(),
4093        "break" => "break_".into(),
4094        "case" => "case_".into(),
4095        "catch" => "catch_".into(),
4096        "char" => "char_".into(),
4097        "char8_t" => "char8_t_".into(),
4098        "char16_t" => "char16_t_".into(),
4099        "char32_t" => "char32_t_".into(),
4100        "class" => "class_".into(),
4101        "compl" => "compl_".into(),
4102        "concept" => "concept_".into(),
4103        "const" => "const_".into(),
4104        "consteval" => "consteval_".into(),
4105        "constexpr" => "constexpr_".into(),
4106        "constinit" => "constinit_".into(),
4107        "const_cast" => "const_cast_".into(),
4108        "continue" => "continue_".into(),
4109        "co_await" => "co_await_".into(),
4110        "co_return" => "co_return_".into(),
4111        "co_yield" => "co_yield_".into(),
4112        "decltype" => "decltype_".into(),
4113        "default" => "default_".into(),
4114        "delete" => "delete_".into(),
4115        "do" => "do_".into(),
4116        "double" => "double_".into(),
4117        "dynamic_cast" => "dynamic_cast_".into(),
4118        "else" => "else_".into(),
4119        "enum" => "enum_".into(),
4120        "explicit" => "explicit_".into(),
4121        "export" => "export_".into(),
4122        "extern" => "extern_".into(),
4123        "false" => "false_".into(),
4124        "float" => "float_".into(),
4125        "for" => "for_".into(),
4126        "friend" => "friend_".into(),
4127        "goto" => "goto_".into(),
4128        "if" => "if_".into(),
4129        "inline" => "inline_".into(),
4130        "int" => "int_".into(),
4131        "long" => "long_".into(),
4132        "mutable" => "mutable_".into(),
4133        "namespace" => "namespace_".into(),
4134        "new" => "new_".into(),
4135        "noexcept" => "noexcept_".into(),
4136        "not" => "not_".into(),
4137        "not_eq" => "not_eq_".into(),
4138        "nullptr" => "nullptr_".into(),
4139        "operator" => "operator_".into(),
4140        "or" => "or_".into(),
4141        "or_eq" => "or_eq_".into(),
4142        "private" => "private_".into(),
4143        "protected" => "protected_".into(),
4144        "public" => "public_".into(),
4145        "reflexpr" => "reflexpr_".into(),
4146        "register" => "register_".into(),
4147        "reinterpret_cast" => "reinterpret_cast_".into(),
4148        "requires" => "requires_".into(),
4149        "return" => "return_".into(),
4150        "short" => "short_".into(),
4151        "signed" => "signed_".into(),
4152        "sizeof" => "sizeof_".into(),
4153        "static" => "static_".into(),
4154        "static_assert" => "static_assert_".into(),
4155        "static_cast" => "static_cast_".into(),
4156        "struct" => "struct_".into(),
4157        "switch" => "switch_".into(),
4158        "synchronized" => "synchronized_".into(),
4159        "template" => "template_".into(),
4160        "this" => "this_".into(),
4161        "thread_local" => "thread_local_".into(),
4162        "throw" => "throw_".into(),
4163        "true" => "true_".into(),
4164        "try" => "try_".into(),
4165        "typedef" => "typedef_".into(),
4166        "typeid" => "typeid_".into(),
4167        "typename" => "typename_".into(),
4168        "union" => "union_".into(),
4169        "unsigned" => "unsigned_".into(),
4170        "using" => "using_".into(),
4171        "virtual" => "virtual_".into(),
4172        "void" => "void_".into(),
4173        "volatile" => "volatile_".into(),
4174        "wchar_t" => "wchar_t_".into(),
4175        "while" => "while_".into(),
4176        "xor" => "xor_".into(),
4177        "xor_eq" => "xor_eq_".into(),
4178        "_Packed" => "_Packed_".into(),
4179        // ret and err needs to be escaped because they are used as
4180        //  variable names for option and result flattening.
4181        "ret" => "ret_".into(),
4182        "err" => "err_".into(),
4183        // C standard library macros that conflict when used as identifiers
4184        "stdin" => "stdin_".into(),
4185        "stdout" => "stdout_".into(),
4186        "stderr" => "stderr_".into(),
4187        s => s.to_snake_case(),
4188    }
4189}
4190
4191const POINTER_SIZE_EXPRESSION: &str = "sizeof(void*)";