Skip to main content

wit_bindgen_c/
lib.rs

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