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    // A named type contributes its (interface-local) name to the generated
1072    // type name rather than its structure, so even when its underlying
1073    // representation is primitive it must not be treated as a world-shareable
1074    // "primitive" type. Otherwise two interfaces that each define a
1075    // differently-typed but identically-named type (e.g. `field-value` in two
1076    // versions of `wasi:http/types`) collapse onto the same anonymous type
1077    // name, producing structs with incompatible element pointer types.
1078    // See https://github.com/bytecodealliance/wit-bindgen/issues/1621.
1079    if resolve.types[id].name.is_some() {
1080        return false;
1081    }
1082    match &resolve.types[id].kind {
1083        TypeDefKind::List(elem) => is_prim_type(resolve, elem),
1084
1085        TypeDefKind::Option(ty) => is_prim_type(resolve, ty),
1086
1087        TypeDefKind::Tuple(tuple) => tuple.types.iter().all(|ty| is_prim_type(resolve, ty)),
1088
1089        TypeDefKind::Type(ty) => is_prim_type(resolve, ty),
1090
1091        TypeDefKind::Record(_)
1092        | TypeDefKind::Resource
1093        | TypeDefKind::Handle(_)
1094        | TypeDefKind::Flags(_)
1095        | TypeDefKind::Variant(_)
1096        | TypeDefKind::Enum(_)
1097        | TypeDefKind::Result(_)
1098        | TypeDefKind::Future(_)
1099        | TypeDefKind::Stream(_)
1100        | TypeDefKind::Unknown => false,
1101        TypeDefKind::FixedLengthList(..) => todo!(),
1102        TypeDefKind::Map(key, value) => is_prim_type(resolve, key) && is_prim_type(resolve, value),
1103    }
1104}
1105
1106pub fn push_ty_name(resolve: &Resolve, ty: &Type, src: &mut String) {
1107    match ty {
1108        Type::Bool => src.push_str("bool"),
1109        Type::Char => src.push_str("char32"),
1110        Type::U8 => src.push_str("u8"),
1111        Type::S8 => src.push_str("s8"),
1112        Type::U16 => src.push_str("u16"),
1113        Type::S16 => src.push_str("s16"),
1114        Type::U32 => src.push_str("u32"),
1115        Type::S32 => src.push_str("s32"),
1116        Type::U64 => src.push_str("u64"),
1117        Type::S64 => src.push_str("s64"),
1118        Type::F32 => src.push_str("f32"),
1119        Type::F64 => src.push_str("f64"),
1120        Type::String => src.push_str("string"),
1121        Type::ErrorContext => todo!(),
1122        Type::Id(id) => {
1123            let ty = &resolve.types[*id];
1124            if let Some(name) = &ty.name {
1125                return src.push_str(&name.to_snake_case());
1126            }
1127            match &ty.kind {
1128                TypeDefKind::Type(t) => push_ty_name(resolve, t, src),
1129                TypeDefKind::Record(_)
1130                | TypeDefKind::Resource
1131                | TypeDefKind::Flags(_)
1132                | TypeDefKind::Enum(_)
1133                | TypeDefKind::Variant(_) => {
1134                    unimplemented!()
1135                }
1136                TypeDefKind::Tuple(t) => {
1137                    src.push_str("tuple");
1138                    src.push_str(&t.types.len().to_string());
1139                    for ty in t.types.iter() {
1140                        src.push_str("_");
1141                        push_ty_name(resolve, ty, src);
1142                    }
1143                }
1144                TypeDefKind::Option(ty) => {
1145                    src.push_str("option_");
1146                    push_ty_name(resolve, ty, src);
1147                }
1148                TypeDefKind::Result(r) => {
1149                    src.push_str("result_");
1150                    match &r.ok {
1151                        Some(ty) => push_ty_name(resolve, ty, src),
1152                        None => src.push_str("void"),
1153                    }
1154                    src.push_str("_");
1155                    match &r.err {
1156                        Some(ty) => push_ty_name(resolve, ty, src),
1157                        None => src.push_str("void"),
1158                    }
1159                }
1160                TypeDefKind::List(ty) => {
1161                    src.push_str("list_");
1162                    push_ty_name(resolve, ty, src);
1163                }
1164                TypeDefKind::Future(ty) => {
1165                    src.push_str("future_");
1166                    match ty {
1167                        Some(ty) => push_ty_name(resolve, ty, src),
1168                        None => src.push_str("void"),
1169                    }
1170                }
1171                TypeDefKind::Stream(ty) => {
1172                    src.push_str("stream_");
1173                    match ty {
1174                        Some(ty) => push_ty_name(resolve, ty, src),
1175                        None => src.push_str("void"),
1176                    }
1177                }
1178                TypeDefKind::Handle(Handle::Own(resource)) => {
1179                    src.push_str("own_");
1180                    push_ty_name(resolve, &Type::Id(*resource), src);
1181                }
1182                TypeDefKind::Handle(Handle::Borrow(resource)) => {
1183                    src.push_str("borrow_");
1184                    push_ty_name(resolve, &Type::Id(*resource), src);
1185                }
1186                TypeDefKind::Unknown => unreachable!(),
1187                TypeDefKind::FixedLengthList(..) => todo!(),
1188                TypeDefKind::Map(key, value) => {
1189                    src.push_str("map_");
1190                    push_ty_name(resolve, key, src);
1191                    src.push_str("_");
1192                    push_ty_name(resolve, value, src);
1193                }
1194            }
1195        }
1196    }
1197}
1198
1199pub fn owner_namespace<'a>(
1200    interface: Option<(InterfaceId, &'a WorldKey)>,
1201    in_import: bool,
1202    world: String,
1203    resolve: &Resolve,
1204    id: TypeId,
1205    renamed_interfaces: &HashMap<WorldKey, String>,
1206) -> String {
1207    let ty = &resolve.types[id];
1208    match (ty.owner, interface) {
1209        // If this type is owned by an interface, then we must be generating
1210        // bindings for that interface to proceed.
1211        (TypeOwner::Interface(a), Some((b, key))) if a == b => {
1212            interface_identifier(key, resolve, !in_import, renamed_interfaces)
1213        }
1214        (TypeOwner::Interface(_), None) => unreachable!(),
1215        (TypeOwner::Interface(_), Some(_)) => unreachable!(),
1216
1217        // If this type is owned by a world then we must not be generating
1218        // bindings for an interface.
1219        (TypeOwner::World(_), None) => world.to_snake_case(),
1220        (TypeOwner::World(_), Some(_)) => unreachable!(),
1221
1222        // If this type has no owner then it's an anonymous type. Here it's
1223        // assigned to whatever we happen to be generating bindings for.
1224        (TypeOwner::None, Some((_, key))) => {
1225            interface_identifier(key, resolve, !in_import, renamed_interfaces)
1226        }
1227        (TypeOwner::None, None) => world.to_snake_case(),
1228    }
1229}
1230
1231fn interface_identifier(
1232    interface_id: &WorldKey,
1233    resolve: &Resolve,
1234    in_export: bool,
1235    renamed_interfaces: &HashMap<WorldKey, String>,
1236) -> String {
1237    if let Some(rename) = renamed_interfaces.get(interface_id) {
1238        let mut ns = String::new();
1239        if in_export && matches!(interface_id, WorldKey::Interface(_)) {
1240            ns.push_str("exports_");
1241        }
1242        ns.push_str(rename);
1243        return ns;
1244    }
1245
1246    match interface_id {
1247        WorldKey::Name(name) => name.to_snake_case(),
1248        WorldKey::Interface(id) => {
1249            let mut ns = String::new();
1250            if in_export {
1251                ns.push_str("exports_");
1252            }
1253            let iface = &resolve.interfaces[*id];
1254            let pkg = &resolve.packages[iface.package.unwrap()];
1255            ns.push_str(&pkg.name.namespace.to_snake_case());
1256            ns.push_str("_");
1257            ns.push_str(&pkg.name.name.to_snake_case());
1258            ns.push_str("_");
1259            let pkg_has_multiple_versions = resolve.packages.iter().any(|(_, p)| {
1260                p.name.namespace == pkg.name.namespace
1261                    && p.name.name == pkg.name.name
1262                    && p.name.version != pkg.name.version
1263            });
1264            if pkg_has_multiple_versions {
1265                if let Some(version) = &pkg.name.version {
1266                    let version = version
1267                        .to_string()
1268                        .replace('.', "_")
1269                        .replace('-', "_")
1270                        .replace('+', "_");
1271                    ns.push_str(&version);
1272                    ns.push_str("_");
1273                }
1274            }
1275            ns.push_str(&iface.name.as_ref().unwrap().to_snake_case());
1276            ns
1277        }
1278    }
1279}
1280
1281pub fn c_func_name(
1282    in_import: bool,
1283    resolve: &Resolve,
1284    world: &str,
1285    interface_id: Option<&WorldKey>,
1286    func: &Function,
1287    renamed_interfaces: &HashMap<WorldKey, String>,
1288) -> String {
1289    let mut name = String::new();
1290    match interface_id {
1291        Some(id) => name.push_str(&interface_identifier(
1292            id,
1293            resolve,
1294            !in_import,
1295            renamed_interfaces,
1296        )),
1297        None => {
1298            if !in_import {
1299                name.push_str("exports_");
1300            }
1301            name.push_str(&world.to_snake_case());
1302        }
1303    }
1304    name.push_str("_");
1305    name.push_str(&func.name.to_snake_case().replace('.', "_"));
1306    name
1307}
1308
1309struct InterfaceGenerator<'a> {
1310    src: Source,
1311    in_import: bool,
1312    r#gen: &'a mut C,
1313    resolve: &'a Resolve,
1314    interface: Option<(InterfaceId, &'a WorldKey)>,
1315    wasm_import_module: Option<&'a str>,
1316}
1317
1318impl C {
1319    fn print_intrinsics(&mut self) {
1320        // Note that these intrinsics are declared as `weak` so they can be
1321        // overridden from some other symbol.
1322        self.src.c_fns("\n// Canonical ABI intrinsics");
1323        self.src.c_fns("\n");
1324        self.src.c_fns(
1325            r#"
1326                __attribute__((__weak__, __export_name__("cabi_realloc")))
1327                void *cabi_realloc(void *ptr, size_t old_size, size_t align, size_t new_size) {
1328                    (void) old_size;
1329                    if (new_size == 0) return (void*) align;
1330                    void *ret = realloc(ptr, new_size);
1331                    if (!ret) abort();
1332                    return ret;
1333                }
1334            "#,
1335        );
1336    }
1337}
1338
1339impl Return {
1340    fn return_single(
1341        &mut self,
1342        resolve: &Resolve,
1343        ty: &Type,
1344        orig_ty: &Type,
1345        sig_flattening: bool,
1346    ) {
1347        let id = match ty {
1348            Type::Id(id) => *id,
1349            Type::String => {
1350                self.retptrs.push(*orig_ty);
1351                return;
1352            }
1353            Type::ErrorContext => todo!("return_single for error-context"),
1354            _ => {
1355                self.scalar = Some(Scalar::Type(*orig_ty));
1356                return;
1357            }
1358        };
1359        match &resolve.types[id].kind {
1360            TypeDefKind::Type(t) => return self.return_single(resolve, t, orig_ty, sig_flattening),
1361
1362            // Flags are returned as their bare values, and enums and handles are scalars
1363            TypeDefKind::Flags(_)
1364            | TypeDefKind::Enum(_)
1365            | TypeDefKind::Handle(_)
1366            | TypeDefKind::Future(_)
1367            | TypeDefKind::Stream(_) => {
1368                self.scalar = Some(Scalar::Type(*orig_ty));
1369                return;
1370            }
1371
1372            // Unpack optional returns where a boolean discriminant is
1373            // returned and then the actual type returned is returned
1374            // through a return pointer.
1375            TypeDefKind::Option(ty) => {
1376                if sig_flattening {
1377                    self.scalar = Some(Scalar::OptionBool(*ty));
1378                    self.retptrs.push(*ty);
1379                    return;
1380                }
1381            }
1382
1383            // Unpack a result as a boolean return type, with two
1384            // return pointers for ok and err values
1385            TypeDefKind::Result(r) => {
1386                if sig_flattening {
1387                    if let Some(ok) = r.ok {
1388                        self.retptrs.push(ok);
1389                    }
1390                    if let Some(err) = r.err {
1391                        self.retptrs.push(err);
1392                    }
1393                    self.scalar = Some(Scalar::ResultBool(r.ok, r.err));
1394                    return;
1395                }
1396            }
1397
1398            // These types are always returned indirectly.
1399            TypeDefKind::Tuple(_)
1400            | TypeDefKind::Record(_)
1401            | TypeDefKind::List(_)
1402            | TypeDefKind::Map(..)
1403            | TypeDefKind::Variant(_) => {}
1404
1405            TypeDefKind::Resource => todo!("return_single for resource"),
1406            TypeDefKind::Unknown => unreachable!(),
1407            TypeDefKind::FixedLengthList(..) => todo!(),
1408        }
1409
1410        self.retptrs.push(*orig_ty);
1411    }
1412}
1413
1414impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
1415    fn resolve(&self) -> &'a Resolve {
1416        self.resolve
1417    }
1418
1419    fn type_record(&mut self, id: TypeId, _name: &str, record: &Record, docs: &Docs) {
1420        self.src.h_defs("\n");
1421        self.docs(docs, SourceType::HDefs);
1422        self.start_typedef_struct(id);
1423        for field in record.fields.iter() {
1424            self.docs(&field.docs, SourceType::HDefs);
1425            self.print_ty(SourceType::HDefs, &field.ty);
1426            self.src.h_defs(" ");
1427            self.src.h_defs(&to_c_ident(&field.name));
1428            self.src.h_defs(";\n");
1429        }
1430        self.finish_typedef_struct(id);
1431    }
1432
1433    fn type_resource(&mut self, id: TypeId, name: &str, _docs: &Docs) {
1434        let ns = self.owner_namespace(id);
1435        let snake = name.to_snake_case();
1436        let mut own = ns.clone();
1437        let mut borrow = own.clone();
1438        own.push_str("_own");
1439        borrow.push_str("_borrow");
1440        own.push_str("_");
1441        borrow.push_str("_");
1442        own.push_str(&snake);
1443        borrow.push_str(&snake);
1444        own.push_str("_t");
1445        borrow.push_str("_t");
1446
1447        // All resources, whether or not they're imported or exported, get the
1448        // ability to drop handles.
1449        self.src.h_helpers(&format!(
1450            "
1451extern void {ns}_{snake}_drop_own({own} handle);
1452            "
1453        ));
1454        let import_module = if self.in_import {
1455            self.wasm_import_module.unwrap().to_string()
1456        } else {
1457            let module = match self.interface {
1458                Some((_, key)) => self.resolve.name_world_key(key),
1459                None => unimplemented!("resource exports from worlds"),
1460            };
1461            format!("[export]{module}")
1462        };
1463
1464        let drop_fn = format!("__wasm_import_{ns}_{snake}_drop");
1465
1466        self.src.c_helpers(&format!(
1467            r#"
1468__attribute__((__import_module__("{import_module}"), __import_name__("[resource-drop]{name}")))
1469extern void {drop_fn}(int32_t handle);
1470
1471void {ns}_{snake}_drop_own({own} handle) {{
1472    {drop_fn}(handle.__handle);
1473}}
1474            "#
1475        ));
1476
1477        // All resources, whether or not they're imported or exported, have an
1478        // handle-index-based representation for "own" handles.
1479        self.src.h_defs(&format!(
1480            "\ntypedef struct {own} {{\nint32_t __handle;\n}} {own};\n"
1481        ));
1482
1483        if self.in_import {
1484            // For imported resources borrowed handles are represented the same
1485            // way as owned handles. They're given a unique type, however, to
1486            // prevent type confusion at runtime in theory.
1487            self.src.h_defs(&format!(
1488                "\ntypedef struct {borrow} {{\nint32_t __handle;\n}} {borrow};\n"
1489            ));
1490
1491            // Explicit borrow dropping is not required if autodrop is enabled.
1492            if !self.autodrop_enabled() {
1493                // As we have two different types for owned vs borrowed resources,
1494                // but owns and borrows are dropped using the same intrinsic we
1495                // also generate a version of the drop function for borrows that we
1496                // possibly acquire through our exports.
1497                self.src.h_helpers(&format!(
1498                    "\nextern void {ns}_{snake}_drop_borrow({borrow} handle);\n"
1499                ));
1500
1501                self.src.c_helpers(&format!(
1502                    "
1503void {ns}_{snake}_drop_borrow({borrow} handle) {{
1504    __wasm_import_{ns}_{snake}_drop(handle.__handle);
1505}}
1506                "
1507                ));
1508            }
1509
1510            // To handle the two types generated for borrow/own this helper
1511            // function enables converting an own handle to a borrow handle
1512            // which will have the same index internally.
1513            self.src.h_helpers(&format!(
1514                "
1515extern {borrow} {ns}_borrow_{snake}({own} handle);
1516                "
1517            ));
1518
1519            self.src.c_helpers(&format!(
1520                r#"
1521{borrow} {ns}_borrow_{snake}({own} arg) {{
1522    return ({borrow}) {{ arg.__handle }};
1523}}
1524                "#
1525            ));
1526        } else {
1527            // For exported resources first generate a typedef that the user
1528            // will be required to fill in. This is an empty struct.
1529            self.src.h_defs("\n");
1530            self.src.h_defs("typedef struct ");
1531            let ty_name = self.r#gen.type_names[&id].clone();
1532            self.src.h_defs(&ty_name);
1533            self.src.h_defs(" ");
1534            self.print_typedef_target(id);
1535            let (_, key) = self.interface.unwrap();
1536            let module = self.resolve.name_world_key(key);
1537
1538            // Exported resources use a different representation than imports
1539            // for borrows which is a raw pointer to the struct declared just
1540            // above.
1541            self.src
1542                .h_defs(&format!("\ntypedef {ty_name}* {borrow};\n"));
1543
1544            // Exported resources are defined by this module which means they
1545            // get access to more intrinsics:
1546            //
1547            // * construction of a resource (rep to handle)
1548            // * extraction of the representation of a resource (handle to rep)
1549            //
1550            // Additionally users must define a destructor for this resource, so
1551            // declare its prototype here.
1552            self.src.h_helpers(&format!(
1553                "
1554extern {own} {ns}_{snake}_new({ty_name} *rep);
1555extern {ty_name}* {ns}_{snake}_rep({own} handle);
1556void {ns}_{snake}_destructor({ty_name} *rep);
1557                "
1558            ));
1559
1560            self.src.c_helpers(&format!(
1561                r#"
1562__attribute__(( __import_module__("[export]{module}"), __import_name__("[resource-new]{name}")))
1563extern int32_t __wasm_import_{ns}_{snake}_new(int32_t);
1564
1565__attribute__((__import_module__("[export]{module}"), __import_name__("[resource-rep]{name}")))
1566extern int32_t __wasm_import_{ns}_{snake}_rep(int32_t);
1567
1568{own} {ns}_{snake}_new({ty_name} *rep) {{
1569    return ({own}) {{ __wasm_import_{ns}_{snake}_new((int32_t) rep) }};
1570}}
1571
1572{ty_name}* {ns}_{snake}_rep({own} handle) {{
1573    return ({ns}_{snake}_t*) __wasm_import_{ns}_{snake}_rep(handle.__handle);
1574}}
1575
1576__attribute__((__export_name__("{module}#[dtor]{snake}")))
1577void __wasm_export_{ns}_{snake}_dtor({ns}_{snake}_t* arg) {{
1578    {ns}_{snake}_destructor(arg);
1579}}
1580                "#
1581            ));
1582        }
1583
1584        self.r#gen.resources.insert(
1585            id,
1586            ResourceInfo {
1587                own,
1588                borrow,
1589                direction: if self.in_import {
1590                    Direction::Import
1591                } else {
1592                    Direction::Export
1593                },
1594                drop_fn,
1595            },
1596        );
1597    }
1598
1599    fn type_tuple(&mut self, id: TypeId, _name: &str, tuple: &Tuple, docs: &Docs) {
1600        self.src.h_defs("\n");
1601        self.docs(docs, SourceType::HDefs);
1602        self.start_typedef_struct(id);
1603        for (i, ty) in tuple.types.iter().enumerate() {
1604            self.print_ty(SourceType::HDefs, ty);
1605            uwriteln!(self.src.h_defs, " f{i};");
1606        }
1607        self.finish_typedef_struct(id);
1608    }
1609
1610    fn type_flags(&mut self, id: TypeId, name: &str, flags: &Flags, docs: &Docs) {
1611        self.src.h_defs("\n");
1612        self.docs(docs, SourceType::HDefs);
1613        self.src.h_defs("typedef ");
1614        let repr = flags_repr(flags);
1615        self.src.h_defs(int_repr(repr));
1616        self.src.h_defs(" ");
1617        self.print_typedef_target(id);
1618
1619        if flags.flags.len() > 0 {
1620            self.src.h_defs("\n");
1621        }
1622        let ns = self.owner_namespace(id).to_shouty_snake_case();
1623        for (i, flag) in flags.flags.iter().enumerate() {
1624            self.docs(&flag.docs, SourceType::HDefs);
1625            uwriteln!(
1626                self.src.h_defs,
1627                "#define {ns}_{}_{} (1 << {i})",
1628                name.to_shouty_snake_case(),
1629                flag.name.to_shouty_snake_case(),
1630            );
1631        }
1632    }
1633
1634    fn type_variant(&mut self, id: TypeId, name: &str, variant: &Variant, docs: &Docs) {
1635        self.src.h_defs("\n");
1636        self.docs(docs, SourceType::HDefs);
1637        self.start_typedef_struct(id);
1638        self.src.h_defs(int_repr(variant.tag()));
1639        self.src.h_defs(" tag;\n");
1640
1641        let cases_with_data = Vec::from_iter(
1642            variant
1643                .cases
1644                .iter()
1645                .filter_map(|case| case.ty.as_ref().map(|ty| (&case.name, ty))),
1646        );
1647
1648        if !cases_with_data.is_empty() {
1649            self.src.h_defs("union {\n");
1650            for (name, ty) in cases_with_data {
1651                self.print_ty(SourceType::HDefs, ty);
1652                self.src.h_defs(" ");
1653                self.src.h_defs(&to_c_ident(name));
1654                self.src.h_defs(";\n");
1655            }
1656            self.src.h_defs("} val;\n");
1657        }
1658        self.finish_typedef_struct(id);
1659
1660        if variant.cases.len() > 0 {
1661            self.src.h_defs("\n");
1662        }
1663        let ns = self.owner_namespace(id).to_shouty_snake_case();
1664        for (i, case) in variant.cases.iter().enumerate() {
1665            self.docs(&case.docs, SourceType::HDefs);
1666            uwriteln!(
1667                self.src.h_defs,
1668                "#define {ns}_{}_{} {i}",
1669                name.to_shouty_snake_case(),
1670                case.name.to_shouty_snake_case(),
1671            );
1672        }
1673    }
1674
1675    fn type_option(&mut self, id: TypeId, _name: &str, payload: &Type, docs: &Docs) {
1676        self.src.h_defs("\n");
1677        self.docs(docs, SourceType::HDefs);
1678        self.start_typedef_struct(id);
1679        self.src.h_defs("bool is_some;\n");
1680        self.print_ty(SourceType::HDefs, payload);
1681        self.src.h_defs(" val;\n");
1682        self.finish_typedef_struct(id);
1683    }
1684
1685    fn type_result(&mut self, id: TypeId, _name: &str, result: &Result_, docs: &Docs) {
1686        self.src.h_defs("\n");
1687        self.docs(docs, SourceType::HDefs);
1688        self.start_typedef_struct(id);
1689        self.src.h_defs("bool is_err;\n");
1690        if result.ok.is_some() || result.err.is_some() {
1691            self.src.h_defs("union {\n");
1692            if let Some(ok) = result.ok.as_ref() {
1693                self.print_ty(SourceType::HDefs, ok);
1694                self.src.h_defs(" ok;\n");
1695            }
1696            if let Some(err) = result.err.as_ref() {
1697                self.print_ty(SourceType::HDefs, err);
1698                self.src.h_defs(" err;\n");
1699            }
1700            self.src.h_defs("} val;\n");
1701        }
1702        self.finish_typedef_struct(id);
1703    }
1704
1705    fn type_enum(&mut self, id: TypeId, name: &str, enum_: &Enum, docs: &Docs) {
1706        uwrite!(self.src.h_defs, "\n");
1707        self.docs(docs, SourceType::HDefs);
1708        let int_t = int_repr(enum_.tag());
1709        uwrite!(self.src.h_defs, "typedef {int_t} ");
1710        self.print_typedef_target(id);
1711
1712        if enum_.cases.len() > 0 {
1713            self.src.h_defs("\n");
1714        }
1715        let ns = self.owner_namespace(id).to_shouty_snake_case();
1716        for (i, case) in enum_.cases.iter().enumerate() {
1717            self.docs(&case.docs, SourceType::HDefs);
1718            uwriteln!(
1719                self.src.h_defs,
1720                "#define {ns}_{}_{} {i}",
1721                name.to_shouty_snake_case(),
1722                case.name.to_shouty_snake_case(),
1723            );
1724        }
1725    }
1726
1727    fn type_alias(&mut self, id: TypeId, _name: &str, ty: &Type, docs: &Docs) {
1728        // we should skip generating `typedef` for `Resource` types because they aren't even
1729        // defined anywhere, not even in `type_resource`. Only its `Handle` types are defined.
1730        // The aliasing handle types are defined in `define_anonymous_type`.
1731        let target = dealias(self.resolve, id);
1732        if matches!(&self.resolve.types[target].kind, TypeDefKind::Resource) {
1733            return;
1734        }
1735
1736        self.src.h_defs("\n");
1737        self.docs(docs, SourceType::HDefs);
1738        self.src.h_defs("typedef ");
1739        self.print_ty(SourceType::HDefs, ty);
1740        self.src.h_defs(" ");
1741        self.print_typedef_target(id);
1742    }
1743
1744    fn type_list(&mut self, id: TypeId, _name: &str, ty: &Type, docs: &Docs) {
1745        self.src.h_defs("\n");
1746        self.docs(docs, SourceType::HDefs);
1747        self.start_typedef_struct(id);
1748        self.print_ty(SourceType::HDefs, ty);
1749        self.src.h_defs(" *ptr;\n");
1750        self.src.h_defs("size_t len;\n");
1751        self.finish_typedef_struct(id);
1752    }
1753
1754    fn type_fixed_length_list(
1755        &mut self,
1756        _id: TypeId,
1757        _name: &str,
1758        _ty: &Type,
1759        _size: u32,
1760        _docs: &Docs,
1761    ) {
1762        todo!("named fixed-length list types are not yet supported in the C backend")
1763    }
1764
1765    fn type_map(&mut self, id: TypeId, _name: &str, key: &Type, value: &Type, docs: &Docs) {
1766        self.src.h_defs("\n");
1767        self.docs(docs, SourceType::HDefs);
1768        self.print_map_entry_typedef(id, key, value);
1769        self.start_typedef_struct(id);
1770        self.print_map_entry_typename(id);
1771        self.src.h_defs(" *ptr;\n");
1772        self.src.h_defs("size_t len;\n");
1773        self.finish_typedef_struct(id);
1774    }
1775
1776    fn type_future(&mut self, id: TypeId, _name: &str, _ty: &Option<Type>, docs: &Docs) {
1777        self.src.h_defs("\n");
1778        self.docs(docs, SourceType::HDefs);
1779        self.src.h_defs("\ntypedef uint32_t ");
1780        self.print_typedef_target(id);
1781    }
1782
1783    fn type_stream(&mut self, id: TypeId, _name: &str, _ty: &Option<Type>, docs: &Docs) {
1784        self.src.h_defs("\n");
1785        self.docs(docs, SourceType::HDefs);
1786        self.src.h_defs("\ntypedef uint32_t ");
1787        self.print_typedef_target(id);
1788    }
1789
1790    fn type_builtin(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
1791        let _ = (id, name, ty, docs);
1792    }
1793}
1794
1795impl<'a> wit_bindgen_core::AnonymousTypeGenerator<'a> for InterfaceGenerator<'a> {
1796    fn resolve(&self) -> &'a Resolve {
1797        self.resolve
1798    }
1799
1800    fn anonymous_type_handle(&mut self, id: TypeId, handle: &Handle, _docs: &Docs) {
1801        self.src.h_defs("\ntypedef ");
1802        let resource = match handle {
1803            Handle::Borrow(id) | Handle::Own(id) => id,
1804        };
1805        let info = &self.r#gen.resources[&dealias(self.resolve, *resource)];
1806        match handle {
1807            Handle::Borrow(_) => self.src.h_defs(&info.borrow),
1808            Handle::Own(_) => self.src.h_defs(&info.own),
1809        }
1810        self.src.h_defs(" ");
1811        self.print_typedef_target(id);
1812    }
1813
1814    fn anonymous_type_tuple(&mut self, id: TypeId, ty: &Tuple, _docs: &Docs) {
1815        self.src.h_defs("\ntypedef ");
1816        self.src.h_defs("struct {\n");
1817        for (i, t) in ty.types.iter().enumerate() {
1818            let ty = self.r#gen.type_name(t);
1819            uwriteln!(self.src.h_defs, "{ty} f{i};");
1820        }
1821        self.src.h_defs("}");
1822        self.src.h_defs(" ");
1823        self.print_typedef_target(id);
1824    }
1825
1826    fn anonymous_type_option(&mut self, id: TypeId, ty: &Type, _docs: &Docs) {
1827        self.src.h_defs("\ntypedef ");
1828        self.src.h_defs("struct {\n");
1829        self.src.h_defs("bool is_some;\n");
1830        let ty = self.r#gen.type_name(ty);
1831        uwriteln!(self.src.h_defs, "{ty} val;");
1832        self.src.h_defs("}");
1833        self.src.h_defs(" ");
1834        self.print_typedef_target(id);
1835    }
1836
1837    fn anonymous_type_result(&mut self, id: TypeId, ty: &Result_, _docs: &Docs) {
1838        self.src.h_defs("\ntypedef ");
1839        self.src.h_defs(
1840            "struct {
1841                bool is_err;
1842            ",
1843        );
1844        let ok_ty = ty.ok.as_ref();
1845        let err_ty = ty.err.as_ref();
1846        if ok_ty.is_some() || err_ty.is_some() {
1847            self.src.h_defs("union {\n");
1848            if let Some(ok) = ok_ty {
1849                let ty = self.r#gen.type_name(ok);
1850                uwriteln!(self.src.h_defs, "{ty} ok;");
1851            }
1852            if let Some(err) = err_ty {
1853                let ty = self.r#gen.type_name(err);
1854                uwriteln!(self.src.h_defs, "{ty} err;");
1855            }
1856            self.src.h_defs("} val;\n");
1857        }
1858        self.src.h_defs("}");
1859        self.src.h_defs(" ");
1860        self.print_typedef_target(id);
1861    }
1862
1863    fn anonymous_type_list(&mut self, id: TypeId, ty: &Type, _docs: &Docs) {
1864        self.src.h_defs("\ntypedef ");
1865        self.src.h_defs("struct {\n");
1866        let ty = self.r#gen.type_name(ty);
1867        uwriteln!(self.src.h_defs, "{ty} *ptr;");
1868        self.src.h_defs("size_t len;\n");
1869        self.src.h_defs("}");
1870        self.src.h_defs(" ");
1871        self.print_typedef_target(id);
1872    }
1873
1874    fn anonymous_type_future(&mut self, id: TypeId, _ty: &Option<Type>, _docs: &Docs) {
1875        self.src.h_defs("\ntypedef uint32_t ");
1876        self.print_typedef_target(id);
1877    }
1878
1879    fn anonymous_type_stream(&mut self, id: TypeId, _ty: &Option<Type>, _docs: &Docs) {
1880        self.src.h_defs("\ntypedef uint32_t ");
1881        self.print_typedef_target(id);
1882    }
1883
1884    fn anonymous_type_type(&mut self, _id: TypeId, _ty: &Type, _docs: &Docs) {
1885        todo!("print_anonymous_type for type");
1886    }
1887
1888    fn anonymous_type_fixed_length_list(
1889        &mut self,
1890        _id: TypeId,
1891        _ty: &Type,
1892        _size: u32,
1893        _docs: &Docs,
1894    ) {
1895        todo!("print_anonymous_type for fixed length list");
1896    }
1897
1898    fn anonymous_type_map(&mut self, id: TypeId, key: &Type, value: &Type, _docs: &Docs) {
1899        self.print_map_entry_typedef(id, key, value);
1900        self.src.h_defs("\ntypedef ");
1901        self.src.h_defs("struct {\n");
1902        self.print_map_entry_typename(id);
1903        self.src.h_defs(" *ptr;\n");
1904        self.src.h_defs("size_t len;\n");
1905        self.src.h_defs("}");
1906        self.src.h_defs(" ");
1907        self.print_typedef_target(id);
1908    }
1909}
1910
1911pub enum CTypeNameInfo<'a> {
1912    Named { name: &'a str },
1913    Anonymous { is_prim: bool },
1914}
1915
1916/// Generate the type part of a c identifier, missing the namespace and the `_t` suffix.
1917/// Additionally return a `CTypeNameInfo` that describes what sort of name has been produced.
1918pub fn gen_type_name(resolve: &Resolve, ty: TypeId) -> (CTypeNameInfo<'_>, String) {
1919    let mut encoded = String::new();
1920    push_ty_name(resolve, &Type::Id(ty), &mut encoded);
1921    let info = if let Some(name) = &resolve.types[ty].name {
1922        CTypeNameInfo::Named {
1923            name: name.as_ref(),
1924        }
1925    } else {
1926        CTypeNameInfo::Anonymous {
1927            is_prim: is_prim_type_id(resolve, ty),
1928        }
1929    };
1930
1931    (info, encoded)
1932}
1933
1934impl InterfaceGenerator<'_> {
1935    fn define_interface_types(&mut self, id: InterfaceId) {
1936        let mut live = LiveTypes::default();
1937        live.add_interface(self.resolve, id);
1938        self.define_live_types(live);
1939    }
1940
1941    fn define_function_types(&mut self, funcs: &[(&str, &Function)]) {
1942        let mut live = LiveTypes::default();
1943        for (_, func) in funcs {
1944            live.add_func(self.resolve, func);
1945        }
1946        self.define_live_types(live);
1947    }
1948
1949    fn define_live_types(&mut self, live: LiveTypes) {
1950        for ty in live.iter() {
1951            if self.r#gen.type_names.contains_key(&ty) {
1952                continue;
1953            }
1954
1955            let (info, encoded) = gen_type_name(&self.resolve, ty);
1956            match info {
1957                CTypeNameInfo::Named { name } => {
1958                    let typedef_name = format!("{}_{encoded}_t", self.owner_namespace(ty));
1959                    let prev = self.r#gen.type_names.insert(ty, typedef_name.clone());
1960                    assert!(prev.is_none());
1961
1962                    self.define_type(name, ty)
1963                }
1964
1965                CTypeNameInfo::Anonymous { is_prim } => {
1966                    let (defined, name) = if is_prim {
1967                        let namespace = self.r#gen.world.to_snake_case();
1968                        let name = format!("{namespace}_{encoded}_t");
1969                        let new_prim = self.r#gen.prim_names.insert(name.clone());
1970                        (!new_prim, name)
1971                    } else {
1972                        let namespace = self.owner_namespace(ty);
1973                        (false, format!("{namespace}_{encoded}_t"))
1974                    };
1975
1976                    let prev = self.r#gen.type_names.insert(ty, name);
1977                    assert!(prev.is_none());
1978
1979                    if defined {
1980                        continue;
1981                    }
1982
1983                    let kind = &self.resolve.types[ty].kind;
1984                    if let TypeDefKind::Handle(handle) = kind {
1985                        let resource = match handle {
1986                            Handle::Borrow(id) | Handle::Own(id) => id,
1987                        };
1988                        let origin = dealias(self.resolve, *resource);
1989                        if origin == *resource {
1990                            continue;
1991                        }
1992                    }
1993
1994                    self.define_anonymous_type(ty)
1995                }
1996            }
1997
1998            self.define_dtor(ty);
1999        }
2000    }
2001
2002    fn define_dtor(&mut self, id: TypeId) {
2003        let h_helpers_start = self.src.h_helpers.len();
2004        let c_helpers_start = self.src.c_helpers.len();
2005
2006        let name = self.r#gen.type_names[&id].clone();
2007        let prefix = name.strip_suffix("_t").unwrap();
2008
2009        self.src
2010            .h_helpers(&format!("\nvoid {prefix}_free({name} *ptr);\n"));
2011        self.src
2012            .c_helpers(&format!("\nvoid {prefix}_free({name} *ptr) {{\n"));
2013        let c_helpers_body_start = self.src.c_helpers.len();
2014        match &self.resolve.types[id].kind {
2015            TypeDefKind::Type(t) => self.free(t, "ptr"),
2016
2017            TypeDefKind::Flags(_) => {}
2018            TypeDefKind::Enum(_) => {}
2019
2020            TypeDefKind::Record(r) => {
2021                for field in r.fields.iter() {
2022                    self.free(&field.ty, &format!("&ptr->{}", to_c_ident(&field.name)));
2023                }
2024            }
2025
2026            TypeDefKind::Tuple(t) => {
2027                for (i, ty) in t.types.iter().enumerate() {
2028                    self.free(ty, &format!("&ptr->f{i}"));
2029                }
2030            }
2031
2032            TypeDefKind::List(t) => {
2033                self.src.c_helpers("size_t list_len = ptr->len;\n");
2034                uwriteln!(self.src.c_helpers, "if (list_len > 0) {{");
2035                let mut t_name = String::new();
2036                self.r#gen.push_type_name(t, &mut t_name);
2037                self.src
2038                    .c_helpers(&format!("{t_name} *list_ptr = ptr->ptr;\n"));
2039                self.src
2040                    .c_helpers("for (size_t i = 0; i < list_len; i++) {\n");
2041                self.free(t, "&list_ptr[i]");
2042                self.src.c_helpers("}\n");
2043                uwriteln!(self.src.c_helpers, "free(list_ptr);");
2044                uwriteln!(self.src.c_helpers, "}}");
2045            }
2046
2047            TypeDefKind::Variant(v) => {
2048                self.src.c_helpers("switch ((int32_t) ptr->tag) {\n");
2049                for (i, case) in v.cases.iter().enumerate() {
2050                    if let Some(ty) = &case.ty {
2051                        uwriteln!(self.src.c_helpers, "case {}: {{", i);
2052                        let expr = format!("&ptr->val.{}", to_c_ident(&case.name));
2053                        self.free(ty, &expr);
2054                        self.src.c_helpers("break;\n");
2055                        self.src.c_helpers("}\n");
2056                    }
2057                }
2058                self.src.c_helpers("}\n");
2059            }
2060
2061            TypeDefKind::Option(t) => {
2062                self.src.c_helpers("if (ptr->is_some) {\n");
2063                self.free(t, "&ptr->val");
2064                self.src.c_helpers("}\n");
2065            }
2066
2067            TypeDefKind::Result(r) => {
2068                self.src.c_helpers("if (!ptr->is_err) {\n");
2069                if let Some(ok) = &r.ok {
2070                    self.free(ok, "&ptr->val.ok");
2071                }
2072                if let Some(err) = &r.err {
2073                    self.src.c_helpers("} else {\n");
2074                    self.free(err, "&ptr->val.err");
2075                }
2076                self.src.c_helpers("}\n");
2077            }
2078            TypeDefKind::Future(_) | TypeDefKind::Stream(_) => {
2079                self.free(&Type::Id(id), "*ptr");
2080            }
2081            TypeDefKind::Resource => {}
2082            TypeDefKind::Handle(Handle::Borrow(id) | Handle::Own(id)) => {
2083                self.free(&Type::Id(*id), "*ptr");
2084            }
2085            TypeDefKind::Unknown => unreachable!(),
2086            TypeDefKind::FixedLengthList(..) => todo!(),
2087            TypeDefKind::Map(key, value) => {
2088                let entry_name = self.map_entry_typename(id);
2089                self.src.c_helpers("size_t map_len = ptr->len;\n");
2090                uwriteln!(self.src.c_helpers, "if (map_len > 0) {{");
2091                uwriteln!(self.src.c_helpers, "{entry_name} *map_ptr = ptr->ptr;");
2092                self.src
2093                    .c_helpers("for (size_t i = 0; i < map_len; i++) {\n");
2094                self.free(key, "&map_ptr[i].key");
2095                self.free(value, "&map_ptr[i].value");
2096                self.src.c_helpers("}\n");
2097                uwriteln!(self.src.c_helpers, "free(map_ptr);");
2098                uwriteln!(self.src.c_helpers, "}}");
2099            }
2100        }
2101        if c_helpers_body_start == self.src.c_helpers.len() {
2102            self.src.c_helpers.as_mut_string().truncate(c_helpers_start);
2103            self.src.h_helpers.as_mut_string().truncate(h_helpers_start);
2104            return;
2105        }
2106        self.src.c_helpers("}\n");
2107        self.r#gen.dtor_funcs.insert(id, format!("{prefix}_free"));
2108    }
2109
2110    fn free(&mut self, ty: &Type, expr: &str) {
2111        match ty {
2112            Type::Id(id) => {
2113                if let Some(dtor) = self.r#gen.dtor_funcs.get(&id) {
2114                    self.src.c_helpers(&format!("{dtor}({expr});\n"));
2115                }
2116            }
2117            Type::String => {
2118                let snake = self.r#gen.world.to_snake_case();
2119                self.src
2120                    .c_helpers(&format!("{snake}_string_free({expr});\n"));
2121            }
2122            Type::Bool
2123            | Type::U8
2124            | Type::S8
2125            | Type::U16
2126            | Type::S16
2127            | Type::U32
2128            | Type::S32
2129            | Type::U64
2130            | Type::S64
2131            | Type::F32
2132            | Type::F64
2133            | Type::Char => {}
2134            Type::ErrorContext => todo!("error context free"),
2135        }
2136    }
2137
2138    fn c_func_name(&self, interface_id: Option<&WorldKey>, func: &Function) -> String {
2139        c_func_name(
2140            self.in_import,
2141            self.resolve,
2142            &self.r#gen.world,
2143            interface_id,
2144            func,
2145            &self.r#gen.renamed_interfaces,
2146        )
2147    }
2148
2149    fn import(&mut self, interface_name: Option<&WorldKey>, func: &Function) {
2150        let async_ = self
2151            .r#gen
2152            .opts
2153            .async_
2154            .is_async(self.resolve, interface_name, func, true);
2155        if async_ {
2156            self.r#gen.needs_async = true;
2157        }
2158
2159        self.docs(&func.docs, SourceType::HFns);
2160        let (variant, import_prefix) = if async_ {
2161            (AbiVariant::GuestImportAsync, "[async-lower]")
2162        } else {
2163            (AbiVariant::GuestImport, "")
2164        };
2165        let sig = self.resolve.wasm_signature(variant, func);
2166
2167        self.src.c_fns("\n");
2168
2169        // In the private C file, print a function declaration which is the
2170        // actual wasm import that we'll be calling, and this has the raw wasm
2171        // signature.
2172        uwriteln!(
2173            self.src.c_fns,
2174            "__attribute__((__import_module__(\"{}\"), __import_name__(\"{import_prefix}{}\")))",
2175            match interface_name {
2176                Some(name) => self.resolve.name_world_key(name),
2177                None => "$root".to_string(),
2178            },
2179            func.name
2180        );
2181        let name = self.c_func_name(interface_name, func);
2182        let import_name = self.r#gen.names.tmp(&format!("__wasm_import_{name}",));
2183        self.src.c_fns("extern ");
2184        match sig.results.len() {
2185            0 => self.src.c_fns("void"),
2186            1 => self.src.c_fns(wasm_type(sig.results[0])),
2187            _ => unimplemented!("multi-value return not supported"),
2188        }
2189        self.src.c_fns(" ");
2190        self.src.c_fns(&import_name);
2191        self.src.c_fns("(");
2192        for (i, param) in sig.params.iter().enumerate() {
2193            if i > 0 {
2194                self.src.c_fns(", ");
2195            }
2196            self.src.c_fns(wasm_type(*param));
2197        }
2198        if sig.params.len() == 0 {
2199            self.src.c_fns("void");
2200        }
2201        self.src.c_fns(");\n");
2202
2203        // Print the public facing signature into the header, and since that's
2204        // what we are defining also print it into the C file.
2205        self.src.h_fns("extern ");
2206        let c_sig = self.print_sig(interface_name, func, &sig, async_);
2207        self.src.c_adapters("\n");
2208        self.src.c_adapters(&c_sig.sig);
2209        self.src.c_adapters(" {\n");
2210
2211        if async_ {
2212            self.import_body_async(func, c_sig, &sig, &import_name);
2213        } else {
2214            self.import_body_sync(func, c_sig, &import_name);
2215        }
2216
2217        self.src.c_adapters("}\n");
2218
2219        self.generate_async_futures_and_streams("", func, interface_name);
2220    }
2221
2222    fn import_body_sync(&mut self, func: &Function, c_sig: CSig, import_name: &str) {
2223        // construct optional adapters from maybe pointers to real optional
2224        // structs internally
2225        let mut optional_adapters = String::from("");
2226        if !self.r#gen.opts.no_sig_flattening {
2227            for (i, (_, param)) in c_sig.params.iter().enumerate() {
2228                let ty = &func.params[i].ty;
2229                if let Type::Id(id) = ty {
2230                    if let TypeDefKind::Option(_) = &self.resolve.types[*id].kind {
2231                        let ty = self.r#gen.type_name(ty);
2232                        uwrite!(
2233                            optional_adapters,
2234                            "{ty} {param};
2235                            {param}.is_some = maybe_{param} != NULL;"
2236                        );
2237                        uwriteln!(
2238                            optional_adapters,
2239                            "if (maybe_{param}) {{
2240                                {param}.val = *maybe_{param};
2241                            }}",
2242                        );
2243                    }
2244                }
2245            }
2246        }
2247
2248        let mut f = FunctionBindgen::new(self, c_sig, &import_name);
2249        for (pointer, param) in f.sig.params.iter() {
2250            if *pointer {
2251                f.params.push(format!("*{param}"));
2252            } else {
2253                f.params.push(param.clone());
2254            }
2255        }
2256        for ptr in f.sig.retptrs.iter() {
2257            f.locals.insert(ptr).unwrap();
2258        }
2259        f.src.push_str(&optional_adapters);
2260        abi::call(
2261            f.r#gen.resolve,
2262            AbiVariant::GuestImport,
2263            LiftLower::LowerArgsLiftResults,
2264            func,
2265            &mut f,
2266            false,
2267        );
2268
2269        let FunctionBindgen {
2270            src,
2271            import_return_pointer_area_size,
2272            import_return_pointer_area_align,
2273            ..
2274        } = f;
2275
2276        if !import_return_pointer_area_size.is_empty() {
2277            self.src.c_adapters(&format!(
2278                "\
2279                    __attribute__((__aligned__({})))
2280                    uint8_t ret_area[{}];
2281                ",
2282                import_return_pointer_area_align.format(POINTER_SIZE_EXPRESSION),
2283                import_return_pointer_area_size.format(POINTER_SIZE_EXPRESSION),
2284            ));
2285        }
2286
2287        self.src.c_adapters(&String::from(src));
2288    }
2289
2290    fn import_body_async(
2291        &mut self,
2292        func: &Function,
2293        c_sig: CSig,
2294        wasm_sig: &WasmSignature,
2295        import_name: &str,
2296    ) {
2297        let mut params = Vec::new();
2298        if wasm_sig.indirect_params {
2299            params.push(format!("(uint8_t*) {}", c_sig.params[0].1));
2300        } else {
2301            let mut f = FunctionBindgen::new(self, c_sig.clone(), "INVALID");
2302            for (i, Param { ty, .. }) in func.params.iter().enumerate() {
2303                let param = &c_sig.params[i].1;
2304                params.extend(abi::lower_flat(f.r#gen.resolve, &mut f, param.clone(), ty));
2305            }
2306            f.r#gen.src.c_adapters.push_str(&f.src);
2307        }
2308        if func.result.is_some() {
2309            params.push(format!("(uint8_t*) {}", c_sig.params.last().unwrap().1));
2310        }
2311        uwriteln!(
2312            self.src.c_adapters,
2313            "return {import_name}({});",
2314            params.join(", "),
2315        );
2316    }
2317
2318    fn export(&mut self, func: &Function, interface_name: Option<&WorldKey>) {
2319        let async_ = self
2320            .r#gen
2321            .opts
2322            .async_
2323            .is_async(self.resolve, interface_name, func, false);
2324
2325        let (variant, prefix) = if async_ {
2326            self.r#gen.needs_async = true;
2327            (AbiVariant::GuestExportAsync, "[async-lift]")
2328        } else {
2329            (AbiVariant::GuestExport, "")
2330        };
2331
2332        let sig = self.resolve.wasm_signature(variant, func);
2333
2334        self.src.c_fns("\n");
2335
2336        let core_module_name = interface_name.map(|s| self.resolve.name_world_key(s));
2337        let export_name = func.legacy_core_export_name(core_module_name.as_deref());
2338
2339        // Print the actual header for this function into the header file, and
2340        // it's what we'll be calling.
2341        let h_sig = self.print_sig(interface_name, func, &sig, async_);
2342
2343        // Generate, in the C source file, the raw wasm signature that has the
2344        // canonical ABI.
2345        uwriteln!(
2346            self.src.c_adapters,
2347            "\n__attribute__((__export_name__(\"{prefix}{export_name}\")))"
2348        );
2349        let name = self.c_func_name(interface_name, func);
2350        let import_name = self.r#gen.names.tmp(&format!("__wasm_export_{name}"));
2351
2352        let mut f = FunctionBindgen::new(self, h_sig, &import_name);
2353        match sig.results.len() {
2354            0 => f.r#gen.src.c_adapters("void"),
2355            1 => f.r#gen.src.c_adapters(wasm_type(sig.results[0])),
2356            _ => unimplemented!("multi-value return not supported"),
2357        }
2358        f.r#gen.src.c_adapters(" ");
2359        f.r#gen.src.c_adapters(&import_name);
2360        f.r#gen.src.c_adapters("(");
2361        for (i, param) in sig.params.iter().enumerate() {
2362            if i > 0 {
2363                f.r#gen.src.c_adapters(", ");
2364            }
2365            let name = f.locals.tmp("arg");
2366            uwrite!(f.r#gen.src.c_adapters, "{} {}", wasm_type(*param), name);
2367            f.params.push(name);
2368        }
2369        if sig.params.len() == 0 {
2370            f.r#gen.src.c_adapters("void");
2371        }
2372        f.r#gen.src.c_adapters(") {\n");
2373
2374        // Perform all lifting/lowering and append it to our src.
2375        abi::call(
2376            f.r#gen.resolve,
2377            variant,
2378            LiftLower::LiftArgsLowerResults,
2379            func,
2380            &mut f,
2381            async_,
2382        );
2383        let FunctionBindgen {
2384            src,
2385            deferred_task_return,
2386            ..
2387        } = f;
2388        self.src.c_adapters(&src);
2389        self.src.c_adapters("}\n");
2390
2391        if async_ {
2392            let snake = self.r#gen.world.to_snake_case();
2393            let return_ty = match &func.result {
2394                Some(ty) => format!("{} ret", self.r#gen.type_name(ty)),
2395                None => "void".to_string(),
2396            };
2397            let DeferredTaskReturn::Emitted {
2398                body: mut task_return_body,
2399                name: task_return_name,
2400                params: task_return_params,
2401            } = deferred_task_return
2402            else {
2403                unreachable!()
2404            };
2405            let task_return_param_tys = task_return_params
2406                .iter()
2407                .map(|(ty, _expr)| wasm_type(*ty))
2408                .collect::<Vec<_>>()
2409                .join(", ");
2410            let task_return_param_exprs = task_return_params
2411                .iter()
2412                .map(|(_ty, expr)| expr.as_str())
2413                .collect::<Vec<_>>()
2414                .join(", ");
2415            let task_return_body = task_return_body.as_mut_string();
2416            uwriteln!(
2417                self.src.h_fns,
2418                "{snake}_callback_code_t {name}_callback({snake}_event_t *event);",
2419            );
2420            uwriteln!(self.src.h_helpers, "void {name}_return({return_ty});");
2421            let import_module = match interface_name {
2422                Some(name) => self.resolve.name_world_key(name),
2423                None => "$root".to_string(),
2424            };
2425            uwriteln!(
2426                self.src.c_helpers,
2427                r#"
2428__attribute__((__export_name__("[callback]{prefix}{export_name}")))
2429uint32_t {import_name}_callback(uint32_t event_raw, uint32_t waitable, uint32_t code) {{
2430    {snake}_event_t event;
2431    event.event = ({snake}_event_code_t) event_raw;
2432    event.waitable = waitable;
2433    event.code = code;
2434    return {name}_callback(&event);
2435}}
2436
2437__attribute__((__import_module__("[export]{import_module}"), __import_name__("{task_return_name}")))
2438void {import_name}__task_return({task_return_param_tys});
2439
2440void {name}_return({return_ty}) {{
2441    {task_return_body}
2442    {import_name}__task_return({task_return_param_exprs});
2443}}
2444                "#
2445            );
2446        } else if abi::guest_export_needs_post_return(self.resolve, func) {
2447            uwriteln!(
2448                self.src.c_fns,
2449                "__attribute__((__weak__, __export_name__(\"cabi_post_{export_name}\")))"
2450            );
2451            uwrite!(self.src.c_fns, "void {import_name}_post_return(");
2452
2453            let mut params = Vec::new();
2454            let mut c_sig = CSig {
2455                name: String::from("INVALID"),
2456                sig: String::from("INVALID"),
2457                params: Vec::new(),
2458                ret: Return::default(),
2459                retptrs: Vec::new(),
2460            };
2461            for (i, result) in sig.results.iter().enumerate() {
2462                let name = format!("arg{i}");
2463                uwrite!(self.src.c_fns, "{} {name}", wasm_type(*result));
2464                c_sig.params.push((false, name.clone()));
2465                params.push(name);
2466            }
2467            self.src.c_fns.push_str(") {\n");
2468
2469            let mut f = FunctionBindgen::new(self, c_sig, &import_name);
2470            f.params = params;
2471            abi::post_return(f.r#gen.resolve, func, &mut f);
2472            let FunctionBindgen { src, .. } = f;
2473            self.src.c_fns(&src);
2474            self.src.c_fns("}\n");
2475        }
2476
2477        self.generate_async_futures_and_streams("[export]", func, interface_name);
2478    }
2479
2480    fn print_sig(
2481        &mut self,
2482        interface_name: Option<&WorldKey>,
2483        func: &Function,
2484        sig: &WasmSignature,
2485        async_: bool,
2486    ) -> CSig {
2487        let name = self.c_func_name(interface_name, func);
2488        self.r#gen.names.insert(&name).expect("duplicate symbols");
2489
2490        let start = self.src.h_fns.len();
2491        let mut result_rets = false;
2492        let mut result_rets_has_ok_type = false;
2493
2494        let ret = if async_ && !self.in_import {
2495            Return {
2496                scalar: func.result.map(Scalar::Type),
2497                retptrs: Vec::new(),
2498            }
2499        } else {
2500            self.classify_ret(func)
2501        };
2502        if async_ {
2503            let snake = self.r#gen.world.to_snake_case();
2504            if self.in_import {
2505                uwrite!(self.src.h_fns, "{snake}_subtask_status_t");
2506            } else {
2507                uwrite!(self.src.h_fns, "{snake}_callback_code_t");
2508            }
2509        } else {
2510            match &ret.scalar {
2511                None | Some(Scalar::Void) => self.src.h_fns("void"),
2512                Some(Scalar::OptionBool(_id)) => self.src.h_fns("bool"),
2513                Some(Scalar::ResultBool(ok, _err)) => {
2514                    result_rets = true;
2515                    result_rets_has_ok_type = ok.is_some();
2516                    self.src.h_fns("bool");
2517                }
2518                Some(Scalar::Type(ty)) => self.print_ty(SourceType::HFns, ty),
2519            }
2520        }
2521        self.src.h_fns(" ");
2522        self.src.h_fns(&name);
2523        self.src.h_fns("(");
2524        let params;
2525        let mut retptrs = Vec::new();
2526        if async_ && self.in_import {
2527            params = self.print_sig_async_import_params(&name, func, sig);
2528        } else if async_ && !self.in_import {
2529            params = self.print_sig_params(func);
2530        } else {
2531            params = self.print_sig_params(func);
2532            let single_ret = ret.retptrs.len() == 1;
2533            for (i, ty) in ret.retptrs.iter().enumerate() {
2534                if i > 0 || func.params.len() > 0 {
2535                    self.src.h_fns(", ");
2536                }
2537                self.print_ty(SourceType::HFns, ty);
2538                self.src.h_fns(" *");
2539                let name: String = if result_rets {
2540                    assert!(i <= 1);
2541                    if i == 0 && result_rets_has_ok_type {
2542                        "ret".into()
2543                    } else {
2544                        "err".into()
2545                    }
2546                } else if single_ret {
2547                    "ret".into()
2548                } else {
2549                    format!("ret{i}")
2550                };
2551                self.src.h_fns(&name);
2552                retptrs.push(name);
2553            }
2554            if func.params.len() == 0 && ret.retptrs.len() == 0 {
2555                self.src.h_fns("void");
2556            }
2557        }
2558        self.src.h_fns(")");
2559
2560        let sig = self.src.h_fns[start..].to_string();
2561        self.src.h_fns(";\n");
2562
2563        CSig {
2564            sig,
2565            name,
2566            params,
2567            ret,
2568            retptrs,
2569        }
2570    }
2571
2572    fn print_sig_params(&mut self, func: &Function) -> Vec<(bool, String)> {
2573        let mut params = Vec::new();
2574        for (i, Param { name, ty, .. }) in func.params.iter().enumerate() {
2575            if i > 0 {
2576                self.src.h_fns(", ");
2577            }
2578            let pointer = is_arg_by_pointer(self.resolve, ty);
2579            // optional param pointer sig_flattening
2580            let optional_type = if let Type::Id(id) = ty {
2581                if let TypeDefKind::Option(option_ty) = &self.resolve.types[*id].kind {
2582                    if !self.r#gen.opts.no_sig_flattening {
2583                        Some(option_ty)
2584                    } else {
2585                        None
2586                    }
2587                } else {
2588                    None
2589                }
2590            } else {
2591                None
2592            };
2593            let (print_ty, print_name) = if !self.r#gen.opts.no_sig_flattening {
2594                if let Some(option_ty) = optional_type {
2595                    (option_ty, format!("maybe_{}", to_c_ident(name)))
2596                } else {
2597                    (ty, to_c_ident(name))
2598                }
2599            } else {
2600                (ty, to_c_ident(name))
2601            };
2602            self.print_ty(SourceType::HFns, print_ty);
2603            self.src.h_fns(" ");
2604            if pointer {
2605                self.src.h_fns("*");
2606            }
2607            self.src.h_fns(&print_name);
2608            params.push((optional_type.is_none() && pointer, to_c_ident(name)));
2609        }
2610        params
2611    }
2612
2613    fn print_sig_async_import_params(
2614        &mut self,
2615        c_func_name: &str,
2616        func: &Function,
2617        sig: &WasmSignature,
2618    ) -> Vec<(bool, String)> {
2619        let mut params = Vec::new();
2620        let mut printed = false;
2621        if sig.indirect_params {
2622            match &func.params[..] {
2623                [] => {}
2624                [Param { name: _, ty, .. }] => {
2625                    printed = true;
2626                    let name = "arg".to_string();
2627                    self.print_ty(SourceType::HFns, ty);
2628                    self.src.h_fns(" *");
2629                    self.src.h_fns(&name);
2630                    params.push((true, name));
2631                }
2632                multiple => {
2633                    printed = true;
2634                    let names = multiple
2635                        .iter()
2636                        .map(|Param { name, ty, .. }| (to_c_ident(name), self.r#gen.type_name(ty)))
2637                        .collect::<Vec<_>>();
2638                    uwriteln!(self.src.h_defs, "typedef struct {c_func_name}_args {{");
2639                    for (name, ty) in names {
2640                        uwriteln!(self.src.h_defs, "{ty} {name};");
2641                    }
2642                    uwriteln!(self.src.h_defs, "}} {c_func_name}_args_t;");
2643                    uwrite!(self.src.h_fns, "{c_func_name}_args_t *args");
2644                    params.push((true, "args".to_string()));
2645                }
2646            }
2647        } else {
2648            for Param { name, ty, .. } in func.params.iter() {
2649                let name = to_c_ident(name);
2650                if printed {
2651                    self.src.h_fns(", ");
2652                } else {
2653                    printed = true;
2654                }
2655                self.print_ty(SourceType::HFns, ty);
2656                self.src.h_fns(" ");
2657                self.src.h_fns(&name);
2658                params.push((false, name));
2659            }
2660        }
2661        if let Some(ty) = &func.result {
2662            if printed {
2663                self.src.h_fns(", ");
2664            } else {
2665                printed = true;
2666            }
2667            let name = "result".to_string();
2668            self.print_ty(SourceType::HFns, ty);
2669            self.src.h_fns(" *");
2670            self.src.h_fns(&name);
2671            params.push((true, name));
2672        }
2673        if !printed {
2674            self.src.h_fns("void");
2675        }
2676        params
2677    }
2678
2679    fn classify_ret(&mut self, func: &Function) -> Return {
2680        let mut ret = Return::default();
2681        match &func.result {
2682            None => ret.scalar = Some(Scalar::Void),
2683            Some(ty) => {
2684                ret.return_single(self.resolve, ty, ty, !self.r#gen.opts.no_sig_flattening);
2685            }
2686        }
2687        return ret;
2688    }
2689
2690    fn print_typedef_target(&mut self, id: TypeId) {
2691        let name = &self.r#gen.type_names[&id];
2692        self.src.h_defs(&name);
2693        self.src.h_defs(";\n");
2694    }
2695
2696    fn start_typedef_struct(&mut self, id: TypeId) {
2697        let name = &self.r#gen.type_names[&id];
2698        self.src.h_defs("typedef struct ");
2699        self.src.h_defs(&name);
2700        self.src.h_defs(" {\n");
2701    }
2702
2703    fn finish_typedef_struct(&mut self, id: TypeId) {
2704        self.src.h_defs("} ");
2705        self.print_typedef_target(id);
2706    }
2707
2708    /// Returns the typedef name of the synthetic entry struct used as the
2709    /// element type of a `map<K, V>`'s flat-pair representation.
2710    fn map_entry_typename(&self, id: TypeId) -> String {
2711        let map_name = &self.r#gen.type_names[&id];
2712        let prefix = map_name.strip_suffix("_t").unwrap_or(map_name.as_str());
2713        format!("{prefix}_entry_t")
2714    }
2715
2716    fn print_map_entry_typename(&mut self, id: TypeId) {
2717        let entry_name = self.map_entry_typename(id);
2718        self.src.h_defs(&entry_name);
2719    }
2720
2721    /// Emits the `typedef struct { K key; V value; } <map>_entry_t;` companion
2722    /// declaration that precedes the map struct itself.
2723    fn print_map_entry_typedef(&mut self, id: TypeId, key: &Type, value: &Type) {
2724        self.src.h_defs("\ntypedef struct {\n");
2725        self.print_ty(SourceType::HDefs, key);
2726        self.src.h_defs(" key;\n");
2727        self.print_ty(SourceType::HDefs, value);
2728        self.src.h_defs(" value;\n} ");
2729        self.print_map_entry_typename(id);
2730        self.src.h_defs(";\n");
2731    }
2732
2733    fn owner_namespace(&self, id: TypeId) -> String {
2734        owner_namespace(
2735            self.interface,
2736            self.in_import,
2737            self.r#gen.world.clone(),
2738            self.resolve,
2739            id,
2740            &self.r#gen.renamed_interfaces,
2741        )
2742    }
2743
2744    fn print_ty(&mut self, stype: SourceType, ty: &Type) {
2745        self.r#gen
2746            .push_type_name(ty, self.src.src(stype).as_mut_string());
2747    }
2748
2749    fn docs(&mut self, docs: &Docs, stype: SourceType) {
2750        let docs = match &docs.contents {
2751            Some(docs) => docs,
2752            None => return,
2753        };
2754        let src = self.src.src(stype);
2755        for line in docs.trim().lines() {
2756            src.push_str("// ");
2757            src.push_str(line);
2758            src.push_str("\n");
2759        }
2760    }
2761
2762    fn autodrop_enabled(&self) -> bool {
2763        self.r#gen.opts.autodrop_borrows == Enabled::Yes
2764    }
2765
2766    fn contains_droppable_borrow(&self, ty: &Type) -> bool {
2767        if let Type::Id(id) = ty {
2768            match &self.resolve.types[*id].kind {
2769                TypeDefKind::Handle(h) => match h {
2770                    // Handles to imported resources will need to be dropped, if the context
2771                    // they're used in is an export.
2772                    Handle::Borrow(id) => {
2773                        !self.in_import
2774                            && matches!(
2775                                self.r#gen.resources[&dealias(self.resolve, *id)].direction,
2776                                Direction::Import
2777                            )
2778                    }
2779
2780                    Handle::Own(_) => false,
2781                },
2782
2783                TypeDefKind::Resource | TypeDefKind::Flags(_) | TypeDefKind::Enum(_) => false,
2784
2785                TypeDefKind::Record(r) => r
2786                    .fields
2787                    .iter()
2788                    .any(|f| self.contains_droppable_borrow(&f.ty)),
2789
2790                TypeDefKind::Tuple(t) => {
2791                    t.types.iter().any(|ty| self.contains_droppable_borrow(ty))
2792                }
2793
2794                TypeDefKind::Variant(v) => v.cases.iter().any(|case| {
2795                    case.ty
2796                        .as_ref()
2797                        .map_or(false, |ty| self.contains_droppable_borrow(ty))
2798                }),
2799
2800                TypeDefKind::Option(ty) => self.contains_droppable_borrow(ty),
2801
2802                TypeDefKind::Result(r) => {
2803                    r.ok.as_ref()
2804                        .map_or(false, |ty| self.contains_droppable_borrow(ty))
2805                        || r.err
2806                            .as_ref()
2807                            .map_or(false, |ty| self.contains_droppable_borrow(ty))
2808                }
2809
2810                TypeDefKind::List(ty) => self.contains_droppable_borrow(ty),
2811
2812                TypeDefKind::Future(_) | TypeDefKind::Stream(_) => false,
2813
2814                TypeDefKind::Type(ty) => self.contains_droppable_borrow(ty),
2815
2816                TypeDefKind::Unknown => false,
2817                TypeDefKind::FixedLengthList(..) => todo!(),
2818                TypeDefKind::Map(key, value) => {
2819                    self.contains_droppable_borrow(key) || self.contains_droppable_borrow(value)
2820                }
2821            }
2822        } else {
2823            false
2824        }
2825    }
2826
2827    fn generate_async_futures_and_streams(
2828        &mut self,
2829        prefix: &str,
2830        func: &Function,
2831        interface: Option<&WorldKey>,
2832    ) {
2833        let module = format!(
2834            "{prefix}{}",
2835            interface
2836                .map(|name| self.resolve.name_world_key(name))
2837                .unwrap_or_else(|| "$root".into())
2838        );
2839        for (index, ty) in func
2840            .find_futures_and_streams(self.resolve)
2841            .into_iter()
2842            .enumerate()
2843        {
2844            let func_name = &func.name;
2845
2846            match &self.resolve.types[ty].kind {
2847                TypeDefKind::Future(payload_type) => {
2848                    self.generate_async_future_or_stream(
2849                        PayloadFor::Future,
2850                        &module,
2851                        index,
2852                        func_name,
2853                        ty,
2854                        payload_type.as_ref(),
2855                    );
2856                }
2857                TypeDefKind::Stream(payload_type) => {
2858                    self.generate_async_future_or_stream(
2859                        PayloadFor::Stream,
2860                        &module,
2861                        index,
2862                        func_name,
2863                        ty,
2864                        payload_type.as_ref(),
2865                    );
2866                }
2867                _ => unreachable!(),
2868            }
2869        }
2870    }
2871
2872    fn generate_async_future_or_stream(
2873        &mut self,
2874        payload_for: PayloadFor,
2875        module: &str,
2876        index: usize,
2877        func_name: &str,
2878        ty: TypeId,
2879        payload_type: Option<&Type>,
2880    ) {
2881        if !self.r#gen.futures.insert(ty) {
2882            return;
2883        }
2884        let ty = self.r#gen.type_name(&Type::Id(ty));
2885        let name = ty.strip_suffix("_t").unwrap();
2886        let snake = self.r#gen.world.to_snake_case();
2887        let kind = match payload_for {
2888            PayloadFor::Future => "future",
2889            PayloadFor::Stream => "stream",
2890        };
2891        let payload_len_arg = match payload_for {
2892            PayloadFor::Future => "",
2893            PayloadFor::Stream => ", size_t",
2894        };
2895        let (read_arg_ty, read_arg_expr, write_arg_ty, write_arg_expr) =
2896            match (payload_for, payload_type) {
2897                (PayloadFor::Future, None) => ("".to_string(), "NULL", "".to_string(), "NULL"),
2898                (PayloadFor::Future, Some(ty)) => {
2899                    let ty = self.r#gen.type_name(ty);
2900                    (
2901                        format!(", {ty} *buf"),
2902                        "(uint8_t*) buf",
2903                        format!(", const {ty} *buf"),
2904                        "(const uint8_t*) buf",
2905                    )
2906                }
2907                (PayloadFor::Stream, None) => (
2908                    ", size_t amt".to_string(),
2909                    "NULL, amt",
2910                    ", size_t amt".to_string(),
2911                    "NULL, amt",
2912                ),
2913                (PayloadFor::Stream, Some(ty)) => {
2914                    let ty = self.r#gen.type_name(ty);
2915                    (
2916                        format!(", {ty} *buf, size_t amt"),
2917                        "(uint8_t*) buf, amt",
2918                        format!(", const {ty} *buf, size_t amt"),
2919                        "(const uint8_t*) buf, amt",
2920                    )
2921                }
2922            };
2923
2924        // TODO: this is a hack around space-stripping in `source.rs`, ideally
2925        // wouldn't be necessary.
2926        let empty = "";
2927        uwriteln!(
2928            self.src.h_helpers,
2929            r#"
2930typedef uint32_t {name}_writer_t;
2931
2932{ty} {name}_new({name}_writer_t *writer);
2933{snake}_waitable_status_t {name}_read({ty} reader{read_arg_ty});
2934{snake}_waitable_status_t {name}_write({name}_writer_t writer{write_arg_ty});
2935{snake}_waitable_status_t {name}_cancel_read({ty} reader);
2936{snake}_waitable_status_t {name}_cancel_write({name}_writer_t writer);
2937void {name}_drop_readable({ty} reader);{empty}
2938void {name}_drop_writable({name}_writer_t writer);
2939            "#,
2940        );
2941        uwriteln!(
2942            self.src.c_helpers,
2943            r#"
2944__attribute__((__import_module__("{module}"), __import_name__("[{kind}-new-{index}]{func_name}")))
2945extern uint64_t {name}__new(void);
2946__attribute__((__import_module__("{module}"), __import_name__("[async-lower][{kind}-read-{index}]{func_name}")))
2947extern uint32_t {name}__read(uint32_t, uint8_t*{payload_len_arg});
2948__attribute__((__import_module__("{module}"), __import_name__("[async-lower][{kind}-write-{index}]{func_name}")))
2949extern uint32_t {name}__write(uint32_t, const uint8_t*{payload_len_arg});
2950__attribute__((__import_module__("{module}"), __import_name__("[{kind}-cancel-read-{index}]{func_name}")))
2951extern uint32_t {name}__cancel_read(uint32_t);
2952__attribute__((__import_module__("{module}"), __import_name__("[{kind}-cancel-write-{index}]{func_name}")))
2953extern uint32_t {name}__cancel_write(uint32_t);
2954__attribute__((__import_module__("{module}"), __import_name__("[{kind}-drop-readable-{index}]{func_name}")))
2955extern void {name}__drop_readable(uint32_t);
2956__attribute__((__import_module__("{module}"), __import_name__("[{kind}-drop-writable-{index}]{func_name}")))
2957extern void {name}__drop_writable(uint32_t);
2958
2959{ty} {name}_new({name}_writer_t *writer) {{
2960    uint64_t packed = {name}__new();
2961    *writer = (uint32_t) (packed >> 32);
2962    return (uint32_t) packed;
2963}}
2964
2965{snake}_waitable_status_t {name}_read({ty} reader{read_arg_ty}) {{
2966    return {name}__read(reader, {read_arg_expr});
2967}}
2968
2969{snake}_waitable_status_t {name}_write({name}_writer_t writer{write_arg_ty}) {{
2970    return {name}__write(writer, {write_arg_expr});
2971}}
2972
2973{snake}_waitable_status_t {name}_cancel_read({ty} reader){empty} {{
2974    return {name}__cancel_read(reader);
2975}}
2976
2977{snake}_waitable_status_t {name}_cancel_write({name}_writer_t writer) {{
2978    return {name}__cancel_write(writer);
2979}}
2980
2981void {name}_drop_readable({ty} reader){empty} {{
2982    {name}__drop_readable(reader);
2983}}
2984
2985void {name}_drop_writable({name}_writer_t writer) {{
2986    {name}__drop_writable(writer);
2987}}
2988            "#,
2989        );
2990    }
2991}
2992
2993enum PayloadFor {
2994    Future,
2995    Stream,
2996}
2997
2998struct DroppableBorrow {
2999    name: String,
3000    ty: TypeId,
3001}
3002
3003struct FunctionBindgen<'a, 'b> {
3004    r#gen: &'a mut InterfaceGenerator<'b>,
3005    locals: Ns,
3006    src: wit_bindgen_core::Source,
3007    sig: CSig,
3008    func_to_call: &'a str,
3009    block_storage: Vec<wit_bindgen_core::Source>,
3010    blocks: Vec<(String, Vec<String>)>,
3011    payloads: Vec<String>,
3012    params: Vec<String>,
3013    wasm_return: Option<String>,
3014    ret_store_cnt: usize,
3015    import_return_pointer_area_size: ArchitectureSize,
3016    import_return_pointer_area_align: Alignment,
3017
3018    /// State of what to generate for the `task.return` intrinsic in the case
3019    /// that this bindings generator is being used for an async export.
3020    ///
3021    /// This typically stays at `DeferredTaskReturn::None` except for the case
3022    /// of async exports where they'll fill this in after the `CallInterface`
3023    /// instruction. For some more information see the documentation on
3024    /// `DeferredTaskReturn`.
3025    deferred_task_return: DeferredTaskReturn,
3026
3027    /// Borrows observed during lifting an export, that will need to be dropped when the guest
3028    /// function exits.
3029    borrows: Vec<DroppableBorrow>,
3030
3031    /// Forward declarations for temporary storage of borrow copies.
3032    borrow_decls: wit_bindgen_core::Source,
3033}
3034
3035/// State associated with the generation of the `task.return` intrinsic function
3036/// with async exports.
3037enum DeferredTaskReturn {
3038    /// Default state, meaning that either bindings generation isn't happening
3039    /// for an async export or the async export is in the bindings generation
3040    /// mode before `CallInterface`.
3041    None,
3042
3043    /// An async export is having bindings generated and `CallInterface` has
3044    /// been seen. After that instruction the `deferred_task_return` field
3045    /// transitions to this state.
3046    ///
3047    /// This state is then present until the `AsyncTaskReturn` instruction is
3048    /// met at which point this changes to `Emitted` below.
3049    Generating {
3050        /// The previous contents of `self.src` just after the `CallInterface`
3051        /// had its code generator. This is effectively the bindings-generated
3052        /// contents of the export and this will get replaced back into
3053        /// `self.src` once the `AsyncTaskReturn` is generated.
3054        prev_src: wit_bindgen_core::Source,
3055    },
3056
3057    /// An `AsyncTaskReturn` has been seen and all state is now located here to
3058    /// be used for generating the `task.return` intrinsic.
3059    ///
3060    /// This state is only generated during `AsyncTaskReturn` and is used to
3061    /// record everything necessary to generate `task.return` meaning that the
3062    /// in-`FunctionBindgen` state is now "back to normal" where it's intended
3063    /// for the main function having bindings generated.
3064    Emitted {
3065        /// The name of the `task.return` intrinsic that should be imported.
3066        /// Note that this does not include the module.
3067        name: String,
3068        /// The wasm type of each parameter provided to the `task.return`
3069        /// intrinsic as well as the C expression necessary to produce this
3070        /// parameter. The type is used to declare the intrinsic and the C
3071        /// expression is used to call the intrinsic from the generated
3072        /// function.
3073        params: Vec<(WasmType, String)>,
3074        /// The body of the `task.return` intrinsic. This contains the bulk of
3075        /// the lowering code from a function's return value to the canonical
3076        /// ABI.
3077        body: wit_bindgen_core::Source,
3078    },
3079}
3080
3081impl<'a, 'b> FunctionBindgen<'a, 'b> {
3082    fn new(
3083        r#gen: &'a mut InterfaceGenerator<'b>,
3084        sig: CSig,
3085        func_to_call: &'a str,
3086    ) -> FunctionBindgen<'a, 'b> {
3087        let mut locals = Ns::default();
3088        for (_, name) in sig.params.iter() {
3089            locals.insert(name).unwrap();
3090        }
3091        FunctionBindgen {
3092            r#gen,
3093            sig,
3094            locals,
3095            src: Default::default(),
3096            func_to_call,
3097            block_storage: Vec::new(),
3098            blocks: Vec::new(),
3099            payloads: Vec::new(),
3100            params: Vec::new(),
3101            wasm_return: None,
3102            ret_store_cnt: 0,
3103            import_return_pointer_area_size: Default::default(),
3104            import_return_pointer_area_align: Default::default(),
3105            borrow_decls: Default::default(),
3106            borrows: Vec::new(),
3107            deferred_task_return: DeferredTaskReturn::None,
3108        }
3109    }
3110
3111    fn store_op(&mut self, op: &str, loc: &str) {
3112        self.src.push_str(loc);
3113        self.src.push_str(" = ");
3114        self.src.push_str(op);
3115        self.src.push_str(";\n");
3116    }
3117
3118    fn load(
3119        &mut self,
3120        ty: &str,
3121        offset: ArchitectureSize,
3122        operands: &[String],
3123        results: &mut Vec<String>,
3124    ) {
3125        results.push(format!(
3126            "*(({}*) ({} + {}))",
3127            ty,
3128            operands[0],
3129            offset.format(POINTER_SIZE_EXPRESSION)
3130        ));
3131    }
3132
3133    fn load_ext(
3134        &mut self,
3135        ty: &str,
3136        offset: ArchitectureSize,
3137        operands: &[String],
3138        results: &mut Vec<String>,
3139    ) {
3140        self.load(ty, offset, operands, results);
3141        let result = results.pop().unwrap();
3142        results.push(format!("(int32_t) {result}"));
3143    }
3144
3145    fn store(&mut self, ty: &str, offset: ArchitectureSize, operands: &[String]) {
3146        uwriteln!(
3147            self.src,
3148            "*(({}*)({} + {})) = {};",
3149            ty,
3150            operands[1],
3151            offset.format(POINTER_SIZE_EXPRESSION),
3152            operands[0]
3153        );
3154    }
3155
3156    fn store_in_retptr(&mut self, operand: &String) {
3157        self.store_op(
3158            operand,
3159            &format!("*{}", self.sig.retptrs[self.ret_store_cnt]),
3160        );
3161        self.ret_store_cnt = self.ret_store_cnt + 1;
3162    }
3163
3164    fn empty_return_value(&mut self) {
3165        // Empty types have no state, so we don't emit stores for them. But we
3166        // do need to keep track of which return variable we're looking at.
3167        self.ret_store_cnt = self.ret_store_cnt + 1;
3168    }
3169
3170    fn assert_no_droppable_borrows(&self, context: &str, ty: &Type) {
3171        if !self.r#gen.in_import
3172            && self.r#gen.autodrop_enabled()
3173            && self.r#gen.contains_droppable_borrow(ty)
3174        {
3175            panic!("Unable to autodrop borrows in `{context}` values, please disable autodrop")
3176        }
3177    }
3178}
3179
3180impl Bindgen for FunctionBindgen<'_, '_> {
3181    type Operand = String;
3182
3183    fn sizes(&self) -> &SizeAlign {
3184        &self.r#gen.r#gen.sizes
3185    }
3186
3187    fn push_block(&mut self) {
3188        let prev = mem::take(&mut self.src);
3189        self.block_storage.push(prev);
3190    }
3191
3192    fn finish_block(&mut self, operands: &mut Vec<String>) {
3193        let to_restore = self.block_storage.pop().unwrap();
3194        let src = mem::replace(&mut self.src, to_restore);
3195        self.blocks.push((src.into(), mem::take(operands)));
3196    }
3197
3198    fn return_pointer(&mut self, size: ArchitectureSize, align: Alignment) -> String {
3199        let ptr = self.locals.tmp("ptr");
3200
3201        // Use a stack-based return area for imports, because exports need
3202        // their return area to be live until the post-return call.
3203        if self.r#gen.in_import {
3204            self.import_return_pointer_area_size = self.import_return_pointer_area_size.max(size);
3205            self.import_return_pointer_area_align =
3206                self.import_return_pointer_area_align.max(align);
3207            uwriteln!(self.src, "uint8_t *{} = (uint8_t *) &ret_area;", ptr);
3208        } else {
3209            self.r#gen.r#gen.return_pointer_area_size =
3210                self.r#gen.r#gen.return_pointer_area_size.max(size);
3211            self.r#gen.r#gen.return_pointer_area_align =
3212                self.r#gen.r#gen.return_pointer_area_align.max(align);
3213            // Declare a statically-allocated return area.
3214            uwriteln!(self.src, "uint8_t *{} = (uint8_t *) &RET_AREA;", ptr);
3215        }
3216
3217        ptr
3218    }
3219
3220    fn is_list_canonical(&self, resolve: &Resolve, ty: &Type) -> bool {
3221        resolve.all_bits_valid(ty)
3222    }
3223
3224    fn emit(
3225        &mut self,
3226        resolve: &Resolve,
3227        inst: &Instruction<'_>,
3228        operands: &mut Vec<String>,
3229        results: &mut Vec<String>,
3230    ) {
3231        match inst {
3232            Instruction::GetArg { nth } => results.push(self.params[*nth].clone()),
3233            Instruction::I32Const { val } => results.push(val.to_string()),
3234            Instruction::ConstZero { tys } => {
3235                for _ in tys.iter() {
3236                    results.push("0".to_string());
3237                }
3238            }
3239
3240            // TODO: checked?
3241            Instruction::U8FromI32 => results.push(format!("(uint8_t) ({})", operands[0])),
3242            Instruction::S8FromI32 => results.push(format!("(int8_t) ({})", operands[0])),
3243            Instruction::U16FromI32 => results.push(format!("(uint16_t) ({})", operands[0])),
3244            Instruction::S16FromI32 => results.push(format!("(int16_t) ({})", operands[0])),
3245            Instruction::U32FromI32 => results.push(format!("(uint32_t) ({})", operands[0])),
3246            Instruction::S32FromI32 | Instruction::S64FromI64 => results.push(operands[0].clone()),
3247            Instruction::U64FromI64 => results.push(format!("(uint64_t) ({})", operands[0])),
3248
3249            Instruction::I32FromU8
3250            | Instruction::I32FromS8
3251            | Instruction::I32FromU16
3252            | Instruction::I32FromS16
3253            | Instruction::I32FromU32 => {
3254                results.push(format!("(int32_t) ({})", operands[0]));
3255            }
3256            Instruction::I32FromS32 | Instruction::I64FromS64 => results.push(operands[0].clone()),
3257            Instruction::I64FromU64 => {
3258                results.push(format!("(int64_t) ({})", operands[0]));
3259            }
3260
3261            // f32/f64 have the same representation in the import type and in C,
3262            // so no conversions necessary.
3263            Instruction::CoreF32FromF32
3264            | Instruction::CoreF64FromF64
3265            | Instruction::F32FromCoreF32
3266            | Instruction::F64FromCoreF64 => {
3267                results.push(operands[0].clone());
3268            }
3269
3270            // TODO: checked
3271            Instruction::CharFromI32 => {
3272                results.push(format!("(uint32_t) ({})", operands[0]));
3273            }
3274            Instruction::I32FromChar => {
3275                results.push(format!("(int32_t) ({})", operands[0]));
3276            }
3277
3278            Instruction::Bitcasts { casts } => {
3279                for (cast, op) in casts.iter().zip(operands) {
3280                    let op = self.r#gen.r#gen.perform_cast(op, cast);
3281                    results.push(op);
3282                }
3283            }
3284
3285            Instruction::BoolFromI32 | Instruction::I32FromBool => {
3286                results.push(operands[0].clone());
3287            }
3288
3289            Instruction::RecordLower { record, .. } => {
3290                let op = &operands[0];
3291                for f in record.fields.iter() {
3292                    results.push(format!("({}).{}", op, to_c_ident(&f.name)));
3293                }
3294            }
3295            Instruction::RecordLift { ty, record, .. } => {
3296                let name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3297                let mut result = format!("({name}) {{\n");
3298                for (field, op) in record.fields.iter().zip(operands.iter()) {
3299                    let field_ty = self.r#gen.r#gen.type_name(&field.ty);
3300                    uwriteln!(result, "({}) {},", field_ty, op);
3301                }
3302                result.push_str("}");
3303                results.push(result);
3304            }
3305
3306            Instruction::TupleLower { tuple, .. } => {
3307                let op = &operands[0];
3308                for i in 0..tuple.types.len() {
3309                    results.push(format!("({op}).f{i}"));
3310                }
3311            }
3312            Instruction::TupleLift { ty, tuple, .. } => {
3313                let name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3314                let mut result = format!("({name}) {{\n");
3315                for (ty, op) in tuple.types.iter().zip(operands.iter()) {
3316                    let ty = self.r#gen.r#gen.type_name(&ty);
3317                    uwriteln!(result, "({}) {},", ty, op);
3318                }
3319                result.push_str("}");
3320                results.push(result);
3321            }
3322
3323            Instruction::HandleLower { .. } => {
3324                let op = &operands[0];
3325                results.push(format!("({op}).__handle"))
3326            }
3327
3328            Instruction::HandleLift { handle, ty, .. } => match handle {
3329                Handle::Borrow(resource)
3330                    if matches!(
3331                        self.r#gen.r#gen.resources[&dealias(resolve, *resource)].direction,
3332                        Direction::Export
3333                    ) =>
3334                {
3335                    // Here we've received a borrow of a resource which we've exported ourselves, so we can treat
3336                    // it as a raw pointer rather than an opaque handle.
3337                    let op = &operands[0];
3338                    let name = self
3339                        .r#gen
3340                        .r#gen
3341                        .type_name(&Type::Id(dealias(resolve, *resource)));
3342                    results.push(format!("(({name}*) {op})"))
3343                }
3344                _ => {
3345                    let op = &operands[0];
3346                    let name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3347                    results.push(format!("({name}) {{ {op} }}"));
3348
3349                    if let Handle::Borrow(id) = handle {
3350                        if !self.r#gen.in_import && self.r#gen.autodrop_enabled() {
3351                            // Here we've received a borrow of an imported resource, which is the
3352                            // kind we'll need to drop when the exported function is returning.
3353                            let ty = dealias(self.r#gen.resolve, *id);
3354
3355                            let name = self.locals.tmp("borrow");
3356                            uwriteln!(self.borrow_decls, "int32_t {name} = 0;");
3357                            uwriteln!(self.src, "{name} = {op};");
3358
3359                            self.borrows.push(DroppableBorrow { name, ty });
3360                        }
3361                    }
3362                }
3363            },
3364
3365            // TODO: checked
3366            Instruction::FlagsLower { flags, ty, .. } => match flags_repr(flags) {
3367                Int::U8 | Int::U16 | Int::U32 => {
3368                    results.push(operands.pop().unwrap());
3369                }
3370                Int::U64 => {
3371                    let name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3372                    let tmp = self.locals.tmp("flags");
3373                    uwriteln!(self.src, "{name} {tmp} = {};", operands[0]);
3374                    results.push(format!("{tmp} & 0xffffffff"));
3375                    results.push(format!("({tmp} >> 32) & 0xffffffff"));
3376                }
3377            },
3378
3379            Instruction::FlagsLift { flags, ty, .. } => match flags_repr(flags) {
3380                Int::U8 | Int::U16 | Int::U32 => {
3381                    results.push(operands.pop().unwrap());
3382                }
3383                Int::U64 => {
3384                    let name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3385                    let op0 = &operands[0];
3386                    let op1 = &operands[1];
3387                    results.push(format!("(({name}) ({op0})) | ((({name}) ({op1})) << 32)"));
3388                }
3389            },
3390
3391            Instruction::VariantPayloadName => {
3392                let name = self.locals.tmp("payload");
3393                results.push(format!("*{name}"));
3394                self.payloads.push(name);
3395            }
3396
3397            Instruction::VariantLower {
3398                variant,
3399                results: result_types,
3400                ..
3401            } => {
3402                let blocks = self
3403                    .blocks
3404                    .drain(self.blocks.len() - variant.cases.len()..)
3405                    .collect::<Vec<_>>();
3406                let payloads = self
3407                    .payloads
3408                    .drain(self.payloads.len() - variant.cases.len()..)
3409                    .collect::<Vec<_>>();
3410
3411                let mut variant_results = Vec::with_capacity(result_types.len());
3412                for ty in result_types.iter() {
3413                    let name = self.locals.tmp("variant");
3414                    results.push(name.clone());
3415                    self.src.push_str(wasm_type(*ty));
3416                    self.src.push_str(" ");
3417                    self.src.push_str(&name);
3418                    self.src.push_str(";\n");
3419                    variant_results.push(name);
3420                }
3421
3422                let expr_to_match = format!("({}).tag", operands[0]);
3423
3424                uwriteln!(self.src, "switch ((int32_t) {}) {{", expr_to_match);
3425                for (i, ((case, (block, block_results)), payload)) in
3426                    variant.cases.iter().zip(blocks).zip(payloads).enumerate()
3427                {
3428                    uwriteln!(self.src, "case {}: {{", i);
3429                    if let Some(ty) = case.ty.as_ref() {
3430                        let ty = self.r#gen.r#gen.type_name(ty);
3431                        uwrite!(
3432                            self.src,
3433                            "const {} *{} = &({}).val",
3434                            ty,
3435                            payload,
3436                            operands[0],
3437                        );
3438                        self.src.push_str(".");
3439                        self.src.push_str(&to_c_ident(&case.name));
3440                        self.src.push_str(";\n");
3441                    }
3442                    self.src.push_str(&block);
3443
3444                    for (name, result) in variant_results.iter().zip(&block_results) {
3445                        uwriteln!(self.src, "{} = {};", name, result);
3446                    }
3447                    self.src.push_str("break;\n}\n");
3448                }
3449                self.src.push_str("}\n");
3450            }
3451
3452            Instruction::VariantLift { variant, ty, .. } => {
3453                let blocks = self
3454                    .blocks
3455                    .drain(self.blocks.len() - variant.cases.len()..)
3456                    .collect::<Vec<_>>();
3457
3458                let ty = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3459                let result = self.locals.tmp("variant");
3460                uwriteln!(self.src, "{} {};", ty, result);
3461                uwriteln!(self.src, "{}.tag = {};", result, operands[0]);
3462                uwriteln!(self.src, "switch ((int32_t) {}.tag) {{", result);
3463                for (i, (case, (block, block_results))) in
3464                    variant.cases.iter().zip(blocks).enumerate()
3465                {
3466                    uwriteln!(self.src, "case {}: {{", i);
3467                    self.src.push_str(&block);
3468                    assert!(block_results.len() == (case.ty.is_some() as usize));
3469
3470                    if let Some(_) = case.ty.as_ref() {
3471                        let mut dst = format!("{result}.val");
3472                        dst.push_str(".");
3473                        dst.push_str(&to_c_ident(&case.name));
3474                        self.store_op(&block_results[0], &dst);
3475                    }
3476                    self.src.push_str("break;\n}\n");
3477                }
3478                self.src.push_str("}\n");
3479                results.push(result);
3480            }
3481
3482            Instruction::OptionLower {
3483                results: result_types,
3484                payload,
3485                ..
3486            } => {
3487                let (mut some, some_results) = self.blocks.pop().unwrap();
3488                let (mut none, none_results) = self.blocks.pop().unwrap();
3489                let some_payload = self.payloads.pop().unwrap();
3490                let _none_payload = self.payloads.pop().unwrap();
3491
3492                for (i, ty) in result_types.iter().enumerate() {
3493                    let name = self.locals.tmp("option");
3494                    results.push(name.clone());
3495                    self.src.push_str(wasm_type(*ty));
3496                    self.src.push_str(" ");
3497                    self.src.push_str(&name);
3498                    self.src.push_str(";\n");
3499                    let some_result = &some_results[i];
3500                    uwriteln!(some, "{name} = {some_result};");
3501                    let none_result = &none_results[i];
3502                    uwriteln!(none, "{name} = {none_result};");
3503                }
3504
3505                let op0 = &operands[0];
3506                let ty = self.r#gen.r#gen.type_name(payload);
3507                let bind_some = format!("const {ty} *{some_payload} = &({op0}).val;");
3508
3509                uwrite!(
3510                    self.src,
3511                    "\
3512                    if (({op0}).is_some) {{
3513                        {bind_some}
3514                        {some}}} else {{
3515                        {none}}}
3516                    "
3517                );
3518            }
3519
3520            Instruction::OptionLift { ty, .. } => {
3521                let (mut some, some_results) = self.blocks.pop().unwrap();
3522                let (mut none, none_results) = self.blocks.pop().unwrap();
3523                assert!(none_results.len() == 0);
3524                assert!(some_results.len() == 1);
3525                let some_result = &some_results[0];
3526
3527                let ty = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3528                let result = self.locals.tmp("option");
3529                uwriteln!(self.src, "{ty} {result};");
3530                let op0 = &operands[0];
3531                let set_some = format!("{result}.val = {some_result};\n");
3532                if none.len() > 0 {
3533                    none.push('\n');
3534                }
3535                if some.len() > 0 {
3536                    some.push('\n');
3537                }
3538                uwrite!(
3539                    self.src,
3540                    "switch ({op0}) {{
3541                        case 0: {{
3542                            {result}.is_some = false;
3543                            {none}\
3544                            break;
3545                        }}
3546                        case 1: {{
3547                            {result}.is_some = true;
3548                            {some}\
3549                            {set_some}\
3550                            break;
3551                        }}
3552                    }}\n"
3553                );
3554                results.push(result);
3555            }
3556
3557            Instruction::ResultLower {
3558                results: result_types,
3559                result,
3560                ..
3561            } => {
3562                let (mut err, err_results) = self.blocks.pop().unwrap();
3563                let (mut ok, ok_results) = self.blocks.pop().unwrap();
3564                let err_payload = self.payloads.pop().unwrap();
3565                let ok_payload = self.payloads.pop().unwrap();
3566
3567                for (i, ty) in result_types.iter().enumerate() {
3568                    let name = self.locals.tmp("result");
3569                    results.push(name.clone());
3570                    self.src.push_str(wasm_type(*ty));
3571                    self.src.push_str(" ");
3572                    self.src.push_str(&name);
3573                    self.src.push_str(";\n");
3574                    let ok_result = &ok_results[i];
3575                    uwriteln!(ok, "{name} = {ok_result};");
3576                    let err_result = &err_results[i];
3577                    uwriteln!(err, "{name} = {err_result};");
3578                }
3579
3580                let op0 = &operands[0];
3581                let bind_ok = if let Some(ok) = result.ok.as_ref() {
3582                    let ok_ty = self.r#gen.r#gen.type_name(ok);
3583                    format!("const {ok_ty} *{ok_payload} = &({op0}).val.ok;")
3584                } else {
3585                    String::new()
3586                };
3587                let bind_err = if let Some(err) = result.err.as_ref() {
3588                    let err_ty = self.r#gen.r#gen.type_name(err);
3589                    format!("const {err_ty} *{err_payload} = &({op0}).val.err;")
3590                } else {
3591                    String::new()
3592                };
3593                uwrite!(
3594                    self.src,
3595                    "\
3596                    if (({op0}).is_err) {{
3597                        {bind_err}\
3598                        {err}\
3599                    }} else {{
3600                        {bind_ok}\
3601                        {ok}\
3602                    }}
3603                    "
3604                );
3605            }
3606
3607            Instruction::ResultLift { result, ty, .. } => {
3608                let (mut err, err_results) = self.blocks.pop().unwrap();
3609                assert!(err_results.len() == (result.err.is_some() as usize));
3610                let (mut ok, ok_results) = self.blocks.pop().unwrap();
3611                assert!(ok_results.len() == (result.ok.is_some() as usize));
3612
3613                if err.len() > 0 {
3614                    err.push_str("\n");
3615                }
3616                if ok.len() > 0 {
3617                    ok.push_str("\n");
3618                }
3619
3620                let result_tmp = self.locals.tmp("result");
3621                let set_ok = if let Some(_) = result.ok.as_ref() {
3622                    let ok_result = &ok_results[0];
3623                    format!("{result_tmp}.val.ok = {ok_result};\n")
3624                } else {
3625                    String::new()
3626                };
3627                let set_err = if let Some(_) = result.err.as_ref() {
3628                    let err_result = &err_results[0];
3629                    format!("{result_tmp}.val.err = {err_result};\n")
3630                } else {
3631                    String::new()
3632                };
3633
3634                let ty = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3635                uwriteln!(self.src, "{ty} {result_tmp};");
3636                let op0 = &operands[0];
3637                uwriteln!(
3638                    self.src,
3639                    "switch ({op0}) {{
3640                        case 0: {{
3641                            {result_tmp}.is_err = false;
3642                            {ok}\
3643                            {set_ok}\
3644                            break;
3645                        }}
3646                        case 1: {{
3647                            {result_tmp}.is_err = true;
3648                            {err}\
3649                            {set_err}\
3650                            break;
3651                        }}
3652                    }}"
3653                );
3654                results.push(result_tmp);
3655            }
3656
3657            Instruction::EnumLower { .. } => results.push(format!("(int32_t) {}", operands[0])),
3658            Instruction::EnumLift { .. } => results.push(operands.pop().unwrap()),
3659
3660            Instruction::ListCanonLower { .. } | Instruction::StringLower { .. } => {
3661                results.push(format!("(uint8_t *) ({}).ptr", operands[0]));
3662                results.push(format!("({}).len", operands[0]));
3663            }
3664            Instruction::ListCanonLift { element, ty, .. } => {
3665                self.assert_no_droppable_borrows("list", &Type::Id(*ty));
3666
3667                let list_name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3668                let elem_name = self.r#gen.r#gen.type_name(element);
3669                results.push(format!(
3670                    "({}) {{ ({}*)({}), ({}) }}",
3671                    list_name, elem_name, operands[0], operands[1]
3672                ));
3673            }
3674            Instruction::StringLift { .. } => {
3675                let list_name = self.r#gen.r#gen.type_name(&Type::String);
3676                results.push(format!(
3677                    "({}) {{ ({}*)({}), ({}) }}",
3678                    list_name,
3679                    self.r#gen.r#gen.char_type(),
3680                    operands[0],
3681                    operands[1]
3682                ));
3683            }
3684
3685            Instruction::ListLower { .. } => {
3686                let _body = self.blocks.pop().unwrap();
3687                results.push(format!("(uint8_t *) ({}).ptr", operands[0]));
3688                results.push(format!("({}).len", operands[0]));
3689            }
3690
3691            Instruction::ListLift { element, ty, .. } => {
3692                self.assert_no_droppable_borrows("list", &Type::Id(*ty));
3693
3694                let _body = self.blocks.pop().unwrap();
3695                let list_name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3696                let elem_name = self.r#gen.r#gen.type_name(element);
3697                results.push(format!(
3698                    "({}) {{ ({}*)({}), ({}) }}",
3699                    list_name, elem_name, operands[0], operands[1]
3700                ));
3701            }
3702
3703            // Maps share the canonical "flat array of entries" layout with the
3704            // C struct emitted by `type_map`/`anonymous_type_map`, so the body
3705            // block is discarded and we splice `.ptr` / `.len` through directly
3706            // (mirroring how `ListLower`/`ListLift` work above).
3707            Instruction::MapLower { .. } => {
3708                let _body = self.blocks.pop().unwrap();
3709                results.push(format!("(uint8_t *) ({}).ptr", operands[0]));
3710                results.push(format!("({}).len", operands[0]));
3711            }
3712
3713            Instruction::MapLift { ty, .. } => {
3714                self.assert_no_droppable_borrows("map", &Type::Id(*ty));
3715
3716                let _body = self.blocks.pop().unwrap();
3717                let map_name = self.r#gen.r#gen.type_name(&Type::Id(*ty));
3718                let entry_name = {
3719                    let prefix = map_name.strip_suffix("_t").unwrap_or(&map_name);
3720                    format!("{prefix}_entry_t")
3721                };
3722                results.push(format!(
3723                    "({}) {{ ({}*)({}), ({}) }}",
3724                    map_name, entry_name, operands[0], operands[1]
3725                ));
3726            }
3727
3728            Instruction::IterElem { .. } => results.push("e".to_string()),
3729            Instruction::IterMapKey { .. } => results.push("map_key".to_string()),
3730            Instruction::IterMapValue { .. } => results.push("map_value".to_string()),
3731            Instruction::IterBasePointer => results.push("base".to_string()),
3732
3733            Instruction::CallWasm { sig, .. } => {
3734                match sig.results.len() {
3735                    0 => {}
3736                    1 => {
3737                        self.src.push_str(wasm_type(sig.results[0]));
3738                        let ret = self.locals.tmp("ret");
3739                        self.wasm_return = Some(ret.clone());
3740                        uwrite!(self.src, " {} = ", ret);
3741                        results.push(ret);
3742                    }
3743                    _ => unimplemented!(),
3744                }
3745                self.src.push_str(self.func_to_call);
3746                self.src.push_str("(");
3747                for (i, op) in operands.iter().enumerate() {
3748                    if i > 0 {
3749                        self.src.push_str(", ");
3750                    }
3751                    self.src.push_str(op);
3752                }
3753                self.src.push_str(");\n");
3754            }
3755
3756            Instruction::CallInterface { func, async_ } => {
3757                let mut args = String::new();
3758                for (i, (op, (byref, _))) in operands.iter().zip(&self.sig.params).enumerate() {
3759                    if i > 0 {
3760                        args.push_str(", ");
3761                    }
3762                    let ty = &func.params[i].ty;
3763                    if *byref {
3764                        let name = self.locals.tmp("arg");
3765                        let ty = self.r#gen.r#gen.type_name(ty);
3766                        uwriteln!(self.src, "{} {} = {};", ty, name, op);
3767                        args.push_str("&");
3768                        args.push_str(&name);
3769                    } else {
3770                        if !self.r#gen.in_import {
3771                            if let Type::Id(id) = ty {
3772                                if let TypeDefKind::Option(_) = &self.r#gen.resolve.types[*id].kind
3773                                {
3774                                    uwrite!(args, "{op}.is_some ? &({op}.val) : NULL");
3775                                    continue;
3776                                }
3777                            }
3778                        }
3779                        args.push_str(op);
3780                    }
3781                }
3782                if *async_ {
3783                    let ret = self.locals.tmp("ret");
3784                    let snake = self.r#gen.r#gen.world.to_snake_case();
3785                    uwriteln!(
3786                        self.src,
3787                        "{snake}_callback_code_t {ret} = {}({args});",
3788                        self.sig.name,
3789                    );
3790                    uwriteln!(self.src, "return {ret};");
3791                    if func.result.is_some() {
3792                        results.push("ret".to_string());
3793                    }
3794                    assert!(matches!(
3795                        self.deferred_task_return,
3796                        DeferredTaskReturn::None
3797                    ));
3798                    self.deferred_task_return = DeferredTaskReturn::Generating {
3799                        prev_src: mem::take(&mut self.src),
3800                    };
3801                    return;
3802                }
3803                match &self.sig.ret.scalar {
3804                    None => {
3805                        let mut retptrs = Vec::new();
3806                        for ty in self.sig.ret.retptrs.iter() {
3807                            let name = self.locals.tmp("ret");
3808                            let ty = self.r#gen.r#gen.type_name(ty);
3809                            uwriteln!(self.src, "{} {};", ty, name);
3810                            if args.len() > 0 {
3811                                args.push_str(", ");
3812                            }
3813                            args.push_str("&");
3814                            args.push_str(&name);
3815                            retptrs.push(name);
3816                        }
3817                        uwriteln!(self.src, "{}({});", self.sig.name, args);
3818                        results.extend(retptrs);
3819                    }
3820                    Some(Scalar::Void) => {
3821                        uwriteln!(self.src, "{}({});", self.sig.name, args);
3822                    }
3823                    Some(Scalar::Type(_)) => {
3824                        let ret = self.locals.tmp("ret");
3825                        let ty = func.result.unwrap();
3826                        let ty = self.r#gen.r#gen.type_name(&ty);
3827                        uwriteln!(self.src, "{} {} = {}({});", ty, ret, self.sig.name, args);
3828                        results.push(ret);
3829                    }
3830                    Some(Scalar::OptionBool(ty)) => {
3831                        let ret = self.locals.tmp("ret");
3832                        let val = self.locals.tmp("val");
3833                        if args.len() > 0 {
3834                            args.push_str(", ");
3835                        }
3836                        args.push_str("&");
3837                        args.push_str(&val);
3838                        let payload_ty = self.r#gen.r#gen.type_name(ty);
3839                        uwriteln!(self.src, "{} {};", payload_ty, val);
3840                        uwriteln!(self.src, "bool {} = {}({});", ret, self.sig.name, args);
3841                        let ty = func.result.unwrap();
3842                        let option_ty = self.r#gen.r#gen.type_name(&ty);
3843                        let option_ret = self.locals.tmp("ret");
3844                        uwrite!(
3845                            self.src,
3846                            "
3847                                {option_ty} {option_ret};
3848                                {option_ret}.is_some = {ret};
3849                                {option_ret}.val = {val};
3850                            ",
3851                        );
3852                        results.push(option_ret);
3853                    }
3854                    Some(Scalar::ResultBool(ok, err)) => {
3855                        let ty = &func.result.unwrap();
3856                        let result_ty = self.r#gen.r#gen.type_name(ty);
3857                        let ret = self.locals.tmp("ret");
3858                        let mut ret_iter = self.sig.ret.retptrs.iter();
3859                        uwriteln!(self.src, "{result_ty} {ret};");
3860                        let ok_name = if ok.is_some() {
3861                            if let Some(ty) = ret_iter.next() {
3862                                let val = self.locals.tmp("ok");
3863                                if args.len() > 0 {
3864                                    uwrite!(args, ", ");
3865                                }
3866                                uwrite!(args, "&{val}");
3867                                let ty = self.r#gen.r#gen.type_name(ty);
3868                                uwriteln!(self.src, "{} {};", ty, val);
3869                                Some(val)
3870                            } else {
3871                                None
3872                            }
3873                        } else {
3874                            None
3875                        };
3876                        let err_name = if let Some(ty) = ret_iter.next() {
3877                            let val = self.locals.tmp("err");
3878                            if args.len() > 0 {
3879                                uwrite!(args, ", ")
3880                            }
3881                            uwrite!(args, "&{val}");
3882                            let ty = self.r#gen.r#gen.type_name(ty);
3883                            uwriteln!(self.src, "{} {};", ty, val);
3884                            Some(val)
3885                        } else {
3886                            None
3887                        };
3888                        assert!(ret_iter.next().is_none());
3889                        uwrite!(self.src, "");
3890                        uwriteln!(self.src, "{ret}.is_err = !{}({args});", self.sig.name);
3891                        if err.is_some() {
3892                            if let Some(err_name) = err_name {
3893                                uwriteln!(
3894                                    self.src,
3895                                    "if ({ret}.is_err) {{
3896                                        {ret}.val.err = {err_name};
3897                                    }}",
3898                                );
3899                            }
3900                        }
3901                        if ok.is_some() {
3902                            if let Some(ok_name) = ok_name {
3903                                uwriteln!(
3904                                    self.src,
3905                                    "if (!{ret}.is_err) {{
3906                                        {ret}.val.ok = {ok_name};
3907                                    }}"
3908                                );
3909                            } else {
3910                                uwrite!(self.src, "\n");
3911                            }
3912                        }
3913                        results.push(ret);
3914                    }
3915                }
3916            }
3917            Instruction::Return { .. } if self.r#gen.in_import => match self.sig.ret.scalar {
3918                None => {
3919                    for op in operands.iter() {
3920                        self.store_in_retptr(op);
3921                    }
3922                }
3923                Some(Scalar::Void) => {
3924                    assert!(operands.is_empty());
3925                }
3926                Some(Scalar::Type(_)) => {
3927                    assert_eq!(operands.len(), 1);
3928                    self.src.push_str("return ");
3929                    self.src.push_str(&operands[0]);
3930                    self.src.push_str(";\n");
3931                }
3932                Some(Scalar::OptionBool(_)) => {
3933                    assert_eq!(operands.len(), 1);
3934                    let variant = &operands[0];
3935                    self.store_in_retptr(&format!("{variant}.val"));
3936                    self.src.push_str("return ");
3937                    self.src.push_str(&variant);
3938                    self.src.push_str(".is_some;\n");
3939                }
3940                Some(Scalar::ResultBool(ok, err)) => {
3941                    assert_eq!(operands.len(), 1);
3942                    let variant = &operands[0];
3943                    assert!(self.sig.retptrs.len() <= 2);
3944                    uwriteln!(self.src, "if (!{}.is_err) {{", variant);
3945                    if ok.is_some() {
3946                        if ok.is_some() {
3947                            self.store_in_retptr(&format!("{variant}.val.ok"));
3948                        } else {
3949                            self.empty_return_value();
3950                        }
3951                    }
3952                    uwriteln!(
3953                        self.src,
3954                        "   return 1;
3955                            }} else {{"
3956                    );
3957                    if err.is_some() {
3958                        if err.is_some() {
3959                            self.store_in_retptr(&format!("{variant}.val.err"));
3960                        } else {
3961                            self.empty_return_value();
3962                        }
3963                    }
3964                    uwriteln!(
3965                        self.src,
3966                        "   return 0;
3967                            }}"
3968                    );
3969                    assert_eq!(self.ret_store_cnt, self.sig.retptrs.len());
3970                }
3971            },
3972            Instruction::Return { amt, .. } => {
3973                // Emit all temporary borrow decls
3974                let src = std::mem::replace(&mut self.src, std::mem::take(&mut self.borrow_decls));
3975                self.src.append_src(&src);
3976
3977                for DroppableBorrow { name, ty } in self.borrows.iter() {
3978                    let drop_fn = self.r#gen.r#gen.resources[ty].drop_fn.as_str();
3979                    uwriteln!(self.src, "if ({name} != 0) {{");
3980                    uwriteln!(self.src, "  {drop_fn}({name});");
3981                    uwriteln!(self.src, "}}");
3982                }
3983
3984                assert!(*amt <= 1);
3985                if *amt == 1 {
3986                    uwriteln!(self.src, "return {};", operands[0]);
3987                }
3988            }
3989
3990            Instruction::I32Load { offset } => self.load("int32_t", *offset, operands, results),
3991            Instruction::I64Load { offset } => self.load("int64_t", *offset, operands, results),
3992            Instruction::F32Load { offset } => self.load("float", *offset, operands, results),
3993            Instruction::F64Load { offset } => self.load("double", *offset, operands, results),
3994            Instruction::PointerLoad { offset } => {
3995                self.load("uint8_t *", *offset, operands, results)
3996            }
3997            Instruction::LengthLoad { offset } => self.load("size_t", *offset, operands, results),
3998            Instruction::I32Store { offset } => self.store("int32_t", *offset, operands),
3999            Instruction::I64Store { offset } => self.store("int64_t", *offset, operands),
4000            Instruction::F32Store { offset } => self.store("float", *offset, operands),
4001            Instruction::F64Store { offset } => self.store("double", *offset, operands),
4002            Instruction::I32Store8 { offset } => self.store("int8_t", *offset, operands),
4003            Instruction::I32Store16 { offset } => self.store("int16_t", *offset, operands),
4004            Instruction::PointerStore { offset } => self.store("uint8_t *", *offset, operands),
4005            Instruction::LengthStore { offset } => self.store("size_t", *offset, operands),
4006
4007            Instruction::I32Load8U { offset } => {
4008                self.load_ext("uint8_t", *offset, operands, results)
4009            }
4010            Instruction::I32Load8S { offset } => {
4011                self.load_ext("int8_t", *offset, operands, results)
4012            }
4013            Instruction::I32Load16U { offset } => {
4014                self.load_ext("uint16_t", *offset, operands, results)
4015            }
4016            Instruction::I32Load16S { offset } => {
4017                self.load_ext("int16_t", *offset, operands, results)
4018            }
4019
4020            Instruction::GuestDeallocate { .. } => {
4021                uwriteln!(self.src, "free({});", operands[0]);
4022            }
4023            Instruction::GuestDeallocateString => {
4024                uwriteln!(self.src, "if (({}) > 0) {{", operands[1]);
4025                uwriteln!(self.src, "free({});", operands[0]);
4026                uwriteln!(self.src, "}}");
4027            }
4028            Instruction::GuestDeallocateVariant { blocks } => {
4029                let blocks = self
4030                    .blocks
4031                    .drain(self.blocks.len() - blocks..)
4032                    .collect::<Vec<_>>();
4033
4034                uwriteln!(self.src, "switch ((int32_t) {}) {{", operands[0]);
4035                for (i, (block, results)) in blocks.into_iter().enumerate() {
4036                    assert!(results.is_empty());
4037                    uwriteln!(self.src, "case {}: {{", i);
4038                    self.src.push_str(&block);
4039                    self.src.push_str("break;\n}\n");
4040                }
4041                self.src.push_str("}\n");
4042            }
4043            Instruction::GuestDeallocateList { element } => {
4044                let (body, results) = self.blocks.pop().unwrap();
4045                assert!(results.is_empty());
4046                let len = self.locals.tmp("len");
4047                uwriteln!(self.src, "size_t {len} = {};", operands[1]);
4048                uwriteln!(self.src, "if ({len} > 0) {{");
4049                let ptr = self.locals.tmp("ptr");
4050                uwriteln!(self.src, "uint8_t *{ptr} = {};", operands[0]);
4051                let i = self.locals.tmp("i");
4052                uwriteln!(self.src, "for (size_t {i} = 0; {i} < {len}; {i}++) {{");
4053                let size = self.r#gen.r#gen.sizes.size(element);
4054                uwriteln!(
4055                    self.src,
4056                    "uint8_t *base = {ptr} + {i} * {};",
4057                    size.format(POINTER_SIZE_EXPRESSION)
4058                );
4059                uwriteln!(self.src, "(void) base;");
4060                uwrite!(self.src, "{body}");
4061                uwriteln!(self.src, "}}");
4062                uwriteln!(self.src, "free({ptr});");
4063                uwriteln!(self.src, "}}");
4064            }
4065
4066            Instruction::GuestDeallocateMap { key, value } => {
4067                let (body, results) = self.blocks.pop().unwrap();
4068                assert!(results.is_empty());
4069                let len = self.locals.tmp("len");
4070                uwriteln!(self.src, "size_t {len} = {};", operands[1]);
4071                uwriteln!(self.src, "if ({len} > 0) {{");
4072                let ptr = self.locals.tmp("ptr");
4073                uwriteln!(self.src, "uint8_t *{ptr} = {};", operands[0]);
4074                let i = self.locals.tmp("i");
4075                uwriteln!(self.src, "for (size_t {i} = 0; {i} < {len}; {i}++) {{");
4076                let entry = self.r#gen.r#gen.sizes.record([*key, *value]);
4077                uwriteln!(
4078                    self.src,
4079                    "uint8_t *base = {ptr} + {i} * {};",
4080                    entry.size.format(POINTER_SIZE_EXPRESSION)
4081                );
4082                uwriteln!(self.src, "(void) base;");
4083                uwrite!(self.src, "{body}");
4084                uwriteln!(self.src, "}}");
4085                uwriteln!(self.src, "free({ptr});");
4086                uwriteln!(self.src, "}}");
4087            }
4088
4089            Instruction::Flush { amt } => {
4090                results.extend(operands.iter().take(*amt).cloned());
4091            }
4092
4093            Instruction::AsyncTaskReturn { name, params } => {
4094                let body = match &mut self.deferred_task_return {
4095                    DeferredTaskReturn::Generating { prev_src } => {
4096                        mem::swap(&mut self.src, prev_src);
4097                        mem::take(prev_src)
4098                    }
4099                    _ => unreachable!(),
4100                };
4101                assert_eq!(params.len(), operands.len());
4102                self.deferred_task_return = DeferredTaskReturn::Emitted {
4103                    name: name.to_string(),
4104                    body,
4105                    params: params
4106                        .iter()
4107                        .zip(operands)
4108                        .map(|(a, b)| (*a, b.clone()))
4109                        .collect(),
4110                };
4111            }
4112
4113            Instruction::FutureLift { .. } => {
4114                results.push(format!("((uint32_t) {})", operands[0]));
4115            }
4116            Instruction::FutureLower { .. } => {
4117                results.push(format!("((int32_t) {})", operands[0]));
4118            }
4119            Instruction::StreamLift { .. } => {
4120                results.push(format!("((uint32_t) {})", operands[0]));
4121            }
4122            Instruction::StreamLower { .. } => {
4123                results.push(format!("((int32_t) {})", operands[0]));
4124            }
4125
4126            i => unimplemented!("{:?}", i),
4127        }
4128    }
4129}
4130
4131#[derive(Default, Clone, Copy)]
4132enum SourceType {
4133    #[default]
4134    HDefs,
4135    HFns,
4136    // HHelpers,
4137    // CDefs,
4138    // CFns,
4139    // CHelpers,
4140    // CAdapters,
4141}
4142
4143#[derive(Default)]
4144struct Source {
4145    h_defs: wit_bindgen_core::Source,
4146    h_fns: wit_bindgen_core::Source,
4147    h_helpers: wit_bindgen_core::Source,
4148    h_async: wit_bindgen_core::Source,
4149    c_defs: wit_bindgen_core::Source,
4150    c_fns: wit_bindgen_core::Source,
4151    c_helpers: wit_bindgen_core::Source,
4152    c_adapters: wit_bindgen_core::Source,
4153    c_async: wit_bindgen_core::Source,
4154}
4155
4156impl Source {
4157    fn src(&mut self, stype: SourceType) -> &mut wit_bindgen_core::Source {
4158        match stype {
4159            SourceType::HDefs => &mut self.h_defs,
4160            SourceType::HFns => &mut self.h_fns,
4161        }
4162    }
4163    fn append(&mut self, append_src: &Source) {
4164        self.h_defs.push_str(&append_src.h_defs);
4165        self.h_fns.push_str(&append_src.h_fns);
4166        self.h_helpers.push_str(&append_src.h_helpers);
4167        self.h_async.push_str(&append_src.h_async);
4168        self.c_defs.push_str(&append_src.c_defs);
4169        self.c_fns.push_str(&append_src.c_fns);
4170        self.c_helpers.push_str(&append_src.c_helpers);
4171        self.c_adapters.push_str(&append_src.c_adapters);
4172        self.c_async.push_str(&append_src.c_async);
4173    }
4174    fn h_defs(&mut self, s: &str) {
4175        self.h_defs.push_str(s);
4176    }
4177    fn h_fns(&mut self, s: &str) {
4178        self.h_fns.push_str(s);
4179    }
4180    fn h_helpers(&mut self, s: &str) {
4181        self.h_helpers.push_str(s);
4182    }
4183    fn c_fns(&mut self, s: &str) {
4184        self.c_fns.push_str(s);
4185    }
4186    fn c_helpers(&mut self, s: &str) {
4187        self.c_helpers.push_str(s);
4188    }
4189    fn c_adapters(&mut self, s: &str) {
4190        self.c_adapters.push_str(s);
4191    }
4192}
4193
4194pub fn wasm_type(ty: WasmType) -> &'static str {
4195    match ty {
4196        WasmType::I32 => "int32_t",
4197        WasmType::I64 => "int64_t",
4198        WasmType::F32 => "float",
4199        WasmType::F64 => "double",
4200        WasmType::Pointer => "uint8_t *",
4201        WasmType::PointerOrI64 => "int64_t",
4202        WasmType::Length => "size_t",
4203    }
4204}
4205
4206pub fn int_repr(ty: Int) -> &'static str {
4207    match ty {
4208        Int::U8 => "uint8_t",
4209        Int::U16 => "uint16_t",
4210        Int::U32 => "uint32_t",
4211        Int::U64 => "uint64_t",
4212    }
4213}
4214
4215pub fn flags_repr(f: &Flags) -> Int {
4216    match f.repr() {
4217        FlagsRepr::U8 => Int::U8,
4218        FlagsRepr::U16 => Int::U16,
4219        FlagsRepr::U32(1) => Int::U32,
4220        FlagsRepr::U32(2) => Int::U64,
4221        repr => panic!("unimplemented flags {repr:?}"),
4222    }
4223}
4224
4225pub fn is_arg_by_pointer(resolve: &Resolve, ty: &Type) -> bool {
4226    match ty {
4227        Type::Id(id) => match resolve.types[*id].kind {
4228            TypeDefKind::Type(t) => is_arg_by_pointer(resolve, &t),
4229            TypeDefKind::Variant(_) => true,
4230            TypeDefKind::Option(_) => true,
4231            TypeDefKind::Result(_) => true,
4232            TypeDefKind::Enum(_) => false,
4233            TypeDefKind::Flags(_) => false,
4234            TypeDefKind::Handle(_) => false,
4235            TypeDefKind::Tuple(_)
4236            | TypeDefKind::Record(_)
4237            | TypeDefKind::List(_)
4238            | TypeDefKind::Map(..) => true,
4239            TypeDefKind::Future(_) => false,
4240            TypeDefKind::Stream(_) => false,
4241            TypeDefKind::Resource => todo!("is_arg_by_pointer for resource"),
4242            TypeDefKind::Unknown => unreachable!(),
4243            TypeDefKind::FixedLengthList(..) => todo!(),
4244        },
4245        Type::String => true,
4246        _ => false,
4247    }
4248}
4249
4250pub fn to_c_ident(name: &str) -> String {
4251    match name {
4252        // Escape C and C++ keywords.
4253        // Source: https://en.cppreference.com/w/cpp/keyword
4254        "alignas" => "alignas_".into(),
4255        "alignof" => "alignof_".into(),
4256        "and" => "and_".into(),
4257        "and_eq" => "and_eq_".into(),
4258        "asm" => "asm_".into(),
4259        "atomic_cancel" => "atomic_cancel_".into(),
4260        "atomic_commit" => "atomic_commit_".into(),
4261        "atomic_noexcept" => "atomic_noexcept_".into(),
4262        "auto" => "auto_".into(),
4263        "bitand" => "bitand_".into(),
4264        "bitor" => "bitor_".into(),
4265        "bool" => "bool_".into(),
4266        "break" => "break_".into(),
4267        "case" => "case_".into(),
4268        "catch" => "catch_".into(),
4269        "char" => "char_".into(),
4270        "char8_t" => "char8_t_".into(),
4271        "char16_t" => "char16_t_".into(),
4272        "char32_t" => "char32_t_".into(),
4273        "class" => "class_".into(),
4274        "compl" => "compl_".into(),
4275        "concept" => "concept_".into(),
4276        "const" => "const_".into(),
4277        "consteval" => "consteval_".into(),
4278        "constexpr" => "constexpr_".into(),
4279        "constinit" => "constinit_".into(),
4280        "const_cast" => "const_cast_".into(),
4281        "continue" => "continue_".into(),
4282        "co_await" => "co_await_".into(),
4283        "co_return" => "co_return_".into(),
4284        "co_yield" => "co_yield_".into(),
4285        "decltype" => "decltype_".into(),
4286        "default" => "default_".into(),
4287        "delete" => "delete_".into(),
4288        "do" => "do_".into(),
4289        "double" => "double_".into(),
4290        "dynamic_cast" => "dynamic_cast_".into(),
4291        "else" => "else_".into(),
4292        "enum" => "enum_".into(),
4293        "explicit" => "explicit_".into(),
4294        "export" => "export_".into(),
4295        "extern" => "extern_".into(),
4296        "false" => "false_".into(),
4297        "float" => "float_".into(),
4298        "for" => "for_".into(),
4299        "friend" => "friend_".into(),
4300        "goto" => "goto_".into(),
4301        "if" => "if_".into(),
4302        "inline" => "inline_".into(),
4303        "int" => "int_".into(),
4304        "long" => "long_".into(),
4305        "mutable" => "mutable_".into(),
4306        "namespace" => "namespace_".into(),
4307        "new" => "new_".into(),
4308        "noexcept" => "noexcept_".into(),
4309        "not" => "not_".into(),
4310        "not_eq" => "not_eq_".into(),
4311        "nullptr" => "nullptr_".into(),
4312        "operator" => "operator_".into(),
4313        "or" => "or_".into(),
4314        "or_eq" => "or_eq_".into(),
4315        "private" => "private_".into(),
4316        "protected" => "protected_".into(),
4317        "public" => "public_".into(),
4318        "reflexpr" => "reflexpr_".into(),
4319        "register" => "register_".into(),
4320        "reinterpret_cast" => "reinterpret_cast_".into(),
4321        "requires" => "requires_".into(),
4322        "return" => "return_".into(),
4323        "short" => "short_".into(),
4324        "signed" => "signed_".into(),
4325        "sizeof" => "sizeof_".into(),
4326        "static" => "static_".into(),
4327        "static_assert" => "static_assert_".into(),
4328        "static_cast" => "static_cast_".into(),
4329        "struct" => "struct_".into(),
4330        "switch" => "switch_".into(),
4331        "synchronized" => "synchronized_".into(),
4332        "template" => "template_".into(),
4333        "this" => "this_".into(),
4334        "thread_local" => "thread_local_".into(),
4335        "throw" => "throw_".into(),
4336        "true" => "true_".into(),
4337        "try" => "try_".into(),
4338        "typedef" => "typedef_".into(),
4339        "typeid" => "typeid_".into(),
4340        "typename" => "typename_".into(),
4341        "union" => "union_".into(),
4342        "unsigned" => "unsigned_".into(),
4343        "using" => "using_".into(),
4344        "virtual" => "virtual_".into(),
4345        "void" => "void_".into(),
4346        "volatile" => "volatile_".into(),
4347        "wchar_t" => "wchar_t_".into(),
4348        "while" => "while_".into(),
4349        "xor" => "xor_".into(),
4350        "xor_eq" => "xor_eq_".into(),
4351        "_Packed" => "_Packed_".into(),
4352        // ret and err needs to be escaped because they are used as
4353        //  variable names for option and result flattening.
4354        "ret" => "ret_".into(),
4355        "err" => "err_".into(),
4356        // C standard library macros that conflict when used as identifiers
4357        "stdin" => "stdin_".into(),
4358        "stdout" => "stdout_".into(),
4359        "stderr" => "stderr_".into(),
4360        s => s.to_snake_case(),
4361    }
4362}
4363
4364const POINTER_SIZE_EXPRESSION: &str = "sizeof(void*)";