wai_bindgen_gen_c/
lib.rs

1use heck::*;
2use std::collections::{BTreeSet, HashMap, HashSet};
3use std::fmt::Write;
4use std::mem;
5use wai_bindgen_gen_core::wai_parser::abi::{
6    AbiVariant, Bindgen, Bitcast, Instruction, LiftLower, WasmType,
7};
8use wai_bindgen_gen_core::{uwrite, uwriteln, wai_parser::*, Direction, Files, Generator, Ns};
9
10#[derive(Default)]
11pub struct C {
12    src: Source,
13    in_import: bool,
14    opts: Opts,
15    funcs: HashMap<String, Vec<Func>>,
16    return_pointer_area_size: usize,
17    return_pointer_area_align: usize,
18    sizes: SizeAlign,
19    names: Ns,
20
21    // The set of types that are considered public (aka need to be in the
22    // header file) which are anonymous and we're effectively monomorphizing.
23    // This is discovered lazily when printing type names.
24    public_anonymous_types: BTreeSet<TypeId>,
25
26    // This is similar to `public_anonymous_types` where it's discovered
27    // lazily, but the set here are for private types only used in the
28    // implementation of functions. These types go in the implementation file,
29    // not the header file.
30    private_anonymous_types: BTreeSet<TypeId>,
31
32    // Type definitions for the given `TypeId`. This is printed topologically
33    // at the end.
34    types: HashMap<TypeId, wai_bindgen_gen_core::Source>,
35
36    needs_string: bool,
37}
38
39struct Func {
40    src: Source,
41}
42
43#[derive(Default, Debug, Clone)]
44#[cfg_attr(feature = "structopt", derive(structopt::StructOpt))]
45pub struct Opts {
46    // ...
47}
48
49impl Opts {
50    pub fn build(&self) -> C {
51        let mut r = C::new();
52        r.opts = self.clone();
53        r
54    }
55}
56
57#[derive(Debug)]
58struct Return {
59    splat_tuple: bool,
60    scalar: Option<Scalar>,
61    retptrs: Vec<Type>,
62}
63
64struct CSig {
65    name: String,
66    sig: String,
67    params: Vec<(bool, String)>,
68    ret: Return,
69    retptrs: Vec<String>,
70}
71
72#[derive(Debug)]
73enum Scalar {
74    Void,
75    OptionBool(Type),
76    ExpectedEnum { err: TypeId, max_err: usize },
77    Type(Type),
78}
79
80impl C {
81    pub fn new() -> C {
82        C::default()
83    }
84
85    fn abi_variant(dir: Direction) -> AbiVariant {
86        // This generator uses the obvious direction to ABI variant mapping.
87        match dir {
88            Direction::Export => AbiVariant::GuestExport,
89            Direction::Import => AbiVariant::GuestImport,
90        }
91    }
92
93    fn classify_ret(&mut self, iface: &Interface, func: &Function) -> Return {
94        let mut ret = Return {
95            splat_tuple: false,
96            scalar: None,
97            retptrs: Vec::new(),
98        };
99        ret.return_single(iface, &func.result, &func.result);
100        return ret;
101    }
102
103    fn print_sig(&mut self, iface: &Interface, func: &Function) -> CSig {
104        let name = format!(
105            "{}_{}",
106            iface.name.to_snake_case(),
107            func.name.to_snake_case()
108        );
109        self.names.insert(&name).expect("duplicate symbols");
110        let start = self.src.h.len();
111
112        let ret = self.classify_ret(iface, func);
113        match &ret.scalar {
114            None | Some(Scalar::Void) => self.src.h("void"),
115            Some(Scalar::OptionBool(_id)) => self.src.h("bool"),
116            Some(Scalar::ExpectedEnum { err, .. }) => self.print_ty(iface, &Type::Id(*err)),
117            Some(Scalar::Type(ty)) => self.print_ty(iface, ty),
118        }
119        self.src.h(" ");
120        self.src.h(&name);
121        self.src.h("(");
122        let mut params = Vec::new();
123        for (i, (name, ty)) in func.params.iter().enumerate() {
124            if i > 0 {
125                self.src.h(", ");
126            }
127            self.print_ty(iface, ty);
128            self.src.h(" ");
129            let pointer = self.is_arg_by_pointer(iface, ty);
130            if pointer {
131                self.src.h("*");
132            }
133            let name = name.to_snake_case();
134            self.src.h(&name);
135            params.push((pointer, name));
136        }
137        let mut retptrs = Vec::new();
138        for (i, ty) in ret.retptrs.iter().enumerate() {
139            if i > 0 || func.params.len() > 0 {
140                self.src.h(", ");
141            }
142            self.print_ty(iface, ty);
143            self.src.h(" *");
144            let name = format!("ret{}", i);
145            self.src.h(&name);
146            retptrs.push(name);
147        }
148        if func.params.len() == 0 && ret.retptrs.len() == 0 {
149            self.src.h("void");
150        }
151        self.src.h(")");
152
153        let sig = self.src.h[start..].to_string();
154        self.src.h(";\n");
155
156        CSig {
157            sig,
158            name,
159            params,
160            ret,
161            retptrs,
162        }
163    }
164
165    fn is_arg_by_pointer(&self, iface: &Interface, ty: &Type) -> bool {
166        match ty {
167            Type::Id(id) => match &iface.types[*id].kind {
168                TypeDefKind::Type(t) => self.is_arg_by_pointer(iface, t),
169                TypeDefKind::Variant(_) => true,
170                TypeDefKind::Union(_) => true,
171                TypeDefKind::Option(_) => true,
172                TypeDefKind::Expected(_) => true,
173                TypeDefKind::Enum(_) => false,
174                TypeDefKind::Flags(_) => false,
175                TypeDefKind::Tuple(_) | TypeDefKind::Record(_) | TypeDefKind::List(_) => true,
176                TypeDefKind::Future(_) => todo!("is_arg_by_pointer for future"),
177                TypeDefKind::Stream(_) => todo!("is_arg_by_pointer for stream"),
178            },
179            Type::String => true,
180            _ => false,
181        }
182    }
183
184    fn type_string(&mut self, iface: &Interface, ty: &Type) -> String {
185        // Getting a type string happens during codegen, and by default means
186        // that this is a private type that's being generated. This means we
187        // want to keep track of new anonymous types that are *only* mentioned
188        // in methods like this, so we can place those types in the C file
189        // instead of the header interface file.
190        let prev = mem::take(&mut self.src.h);
191        let prev_public = mem::take(&mut self.public_anonymous_types);
192        let prev_private = mem::take(&mut self.private_anonymous_types);
193
194        // Print the type, which will collect into the fields that we replaced
195        // above.
196        self.print_ty(iface, ty);
197
198        // Reset our public/private sets back to what they were beforehand.
199        // Note that `print_ty` always adds to the public set, so we're
200        // inverting the meaning here by interpreting those as new private
201        // types.
202        let new_private = mem::replace(&mut self.public_anonymous_types, prev_public);
203        assert!(self.private_anonymous_types.is_empty());
204        self.private_anonymous_types = prev_private;
205
206        // For all new private types found while we printed this type, if the
207        // type isn't already public then it's a new private type.
208        for id in new_private {
209            if !self.public_anonymous_types.contains(&id) {
210                self.private_anonymous_types.insert(id);
211            }
212        }
213
214        mem::replace(&mut self.src.h, prev).into()
215    }
216
217    fn print_ty(&mut self, iface: &Interface, ty: &Type) {
218        match ty {
219            Type::Unit => self.src.h("void"),
220            Type::Bool => self.src.h("bool"),
221            Type::Char => self.src.h("uint32_t"), // TODO: better type?
222            Type::U8 => self.src.h("uint8_t"),
223            Type::S8 => self.src.h("int8_t"),
224            Type::U16 => self.src.h("uint16_t"),
225            Type::S16 => self.src.h("int16_t"),
226            Type::U32 => self.src.h("uint32_t"),
227            Type::S32 => self.src.h("int32_t"),
228            Type::U64 => self.src.h("uint64_t"),
229            Type::S64 => self.src.h("int64_t"),
230            Type::Float32 => self.src.h("float"),
231            Type::Float64 => self.src.h("double"),
232            Type::Handle(id) => {
233                self.print_namespace(iface);
234                self.src.h(&iface.resources[*id].name.to_snake_case());
235                self.src.h("_t");
236            }
237            Type::String => {
238                self.print_namespace(iface);
239                self.src.h("string_t");
240                self.needs_string = true;
241            }
242            Type::Id(id) => {
243                let ty = &iface.types[*id];
244                match &ty.name {
245                    Some(name) => {
246                        self.print_namespace(iface);
247                        self.src.h(&name.to_snake_case());
248                        self.src.h("_t");
249                    }
250                    None => match &ty.kind {
251                        TypeDefKind::Type(t) => self.print_ty(iface, t),
252                        _ => {
253                            self.public_anonymous_types.insert(*id);
254                            self.private_anonymous_types.remove(id);
255                            self.print_namespace(iface);
256                            self.print_ty_name(iface, &Type::Id(*id));
257                            self.src.h("_t");
258                        }
259                    },
260                }
261            }
262        }
263    }
264
265    fn print_ty_name(&mut self, iface: &Interface, ty: &Type) {
266        match ty {
267            Type::Unit => self.src.h("unit"),
268            Type::Bool => self.src.h("bool"),
269            Type::Char => self.src.h("char32"),
270            Type::U8 => self.src.h("u8"),
271            Type::S8 => self.src.h("s8"),
272            Type::U16 => self.src.h("u16"),
273            Type::S16 => self.src.h("s16"),
274            Type::U32 => self.src.h("u32"),
275            Type::S32 => self.src.h("s32"),
276            Type::U64 => self.src.h("u64"),
277            Type::S64 => self.src.h("s64"),
278            Type::Float32 => self.src.h("float32"),
279            Type::Float64 => self.src.h("float64"),
280            Type::Handle(id) => self.src.h(&iface.resources[*id].name.to_snake_case()),
281            Type::String => self.src.h("string"),
282            Type::Id(id) => {
283                let ty = &iface.types[*id];
284                if let Some(name) = &ty.name {
285                    return self.src.h(&name.to_snake_case());
286                }
287                match &ty.kind {
288                    TypeDefKind::Type(t) => self.print_ty_name(iface, t),
289                    TypeDefKind::Record(_)
290                    | TypeDefKind::Flags(_)
291                    | TypeDefKind::Enum(_)
292                    | TypeDefKind::Variant(_)
293                    | TypeDefKind::Union(_) => {
294                        unimplemented!()
295                    }
296                    TypeDefKind::Tuple(t) => {
297                        self.src.h("tuple");
298                        self.src.h(&t.types.len().to_string());
299                        for ty in t.types.iter() {
300                            self.src.h("_");
301                            self.print_ty_name(iface, ty);
302                        }
303                    }
304                    TypeDefKind::Option(ty) => {
305                        self.src.h("option_");
306                        self.print_ty_name(iface, ty);
307                    }
308                    TypeDefKind::Expected(e) => {
309                        self.src.h("expected_");
310                        self.print_ty_name(iface, &e.ok);
311                        self.src.h("_");
312                        self.print_ty_name(iface, &e.err);
313                    }
314                    TypeDefKind::List(t) => {
315                        self.src.h("list_");
316                        self.print_ty_name(iface, t);
317                    }
318                    TypeDefKind::Future(t) => {
319                        self.src.h("future_");
320                        self.print_ty_name(iface, t);
321                    }
322                    TypeDefKind::Stream(s) => {
323                        self.src.h("stream_");
324                        self.print_ty_name(iface, &s.element);
325                        self.src.h("_");
326                        self.print_ty_name(iface, &s.end);
327                    }
328                }
329            }
330        }
331    }
332
333    fn print_anonymous_type(&mut self, iface: &Interface, ty: TypeId) {
334        let prev = mem::take(&mut self.src.h);
335        self.src.h("typedef ");
336        let kind = &iface.types[ty].kind;
337        match kind {
338            TypeDefKind::Type(_)
339            | TypeDefKind::Flags(_)
340            | TypeDefKind::Record(_)
341            | TypeDefKind::Enum(_)
342            | TypeDefKind::Variant(_)
343            | TypeDefKind::Union(_) => {
344                unreachable!()
345            }
346            TypeDefKind::Tuple(t) => {
347                self.src.h("struct {\n");
348                for (i, t) in t.types.iter().enumerate() {
349                    self.print_ty(iface, t);
350                    uwriteln!(self.src.h, " f{i};");
351                }
352                self.src.h("}");
353            }
354            TypeDefKind::Option(t) => {
355                self.src.h("struct {\n");
356                self.src.h("bool is_some;\n");
357                if !self.is_empty_type(iface, t) {
358                    self.print_ty(iface, t);
359                    self.src.h(" val;\n");
360                }
361                self.src.h("}");
362            }
363            TypeDefKind::Expected(e) => {
364                self.src.h("struct {
365                    bool is_err;
366                    union {
367                ");
368                if !self.is_empty_type(iface, &e.ok) {
369                    self.print_ty(iface, &e.ok);
370                    self.src.h(" ok;\n");
371                }
372                if !self.is_empty_type(iface, &e.err) {
373                    self.print_ty(iface, &e.err);
374                    self.src.h(" err;\n");
375                }
376                self.src.h("} val;\n");
377                self.src.h("}");
378            }
379            TypeDefKind::List(t) => {
380                self.src.h("struct {\n");
381                self.print_ty(iface, t);
382                self.src.h(" *ptr;\n");
383                self.src.h("size_t len;\n");
384                self.src.h("}");
385            }
386            TypeDefKind::Future(_) => todo!("print_anonymous_type for future"),
387            TypeDefKind::Stream(_) => todo!("print_anonymous_type for stream"),
388        }
389        self.src.h(" ");
390        self.print_namespace(iface);
391        self.print_ty_name(iface, &Type::Id(ty));
392        self.src.h("_t;\n");
393        self.types.insert(ty, mem::replace(&mut self.src.h, prev));
394    }
395
396    fn is_empty_type(&self, iface: &Interface, ty: &Type) -> bool {
397        let id = match ty {
398            Type::Id(id) => *id,
399            Type::Unit => return true,
400            _ => return false,
401        };
402        match &iface.types[id].kind {
403            TypeDefKind::Type(t) => self.is_empty_type(iface, t),
404            TypeDefKind::Record(r) => r.fields.is_empty(),
405            TypeDefKind::Tuple(t) => t.types.is_empty(),
406            _ => false,
407        }
408    }
409
410    fn print_intrinsics(&mut self) {
411        // Note that these intrinsics are declared as `weak` so they can be
412        // overridden from some other symbol.
413        self.src.c("
414            __attribute__((weak, export_name(\"canonical_abi_realloc\")))
415            void *canonical_abi_realloc(
416                void *ptr,
417                size_t orig_size,
418                size_t org_align,
419                size_t new_size
420            ) {
421                void *ret = realloc(ptr, new_size);
422                if (!ret)
423                    abort();
424                return ret;
425            }
426
427            __attribute__((weak, export_name(\"canonical_abi_free\")))
428            void canonical_abi_free(
429                void *ptr,
430                size_t size,
431                size_t align
432            ) {
433                free(ptr);
434            }
435        ");
436    }
437
438    fn print_namespace(&mut self, iface: &Interface) {
439        self.src.h(&iface.name.to_snake_case());
440        self.src.h("_");
441    }
442
443    fn print_dtor(&mut self, iface: &Interface, id: TypeId) {
444        let ty = Type::Id(id);
445        if !self.owns_anything(iface, &ty) {
446            return;
447        }
448        let pos = self.src.h.len();
449        self.src.h("void ");
450        self.print_namespace(iface);
451        self.print_ty_name(iface, &ty);
452        self.src.h("_free(");
453        self.print_namespace(iface);
454        self.print_ty_name(iface, &ty);
455        self.src.h("_t *ptr)");
456
457        self.src.c(&self.src.h[pos..].to_string());
458        self.src.h(";\n");
459        self.src.c(" {\n");
460        match &iface.types[id].kind {
461            TypeDefKind::Type(t) => self.free(iface, t, "ptr"),
462
463            TypeDefKind::Flags(_) => {}
464            TypeDefKind::Enum(_) => {}
465
466            TypeDefKind::Record(r) => {
467                for field in r.fields.iter() {
468                    if !self.owns_anything(iface, &field.ty) {
469                        continue;
470                    }
471                    self.free(
472                        iface,
473                        &field.ty,
474                        &format!("&ptr->{}", field.name.to_snake_case()),
475                    );
476                }
477            }
478
479            TypeDefKind::Tuple(t) => {
480                for (i, ty) in t.types.iter().enumerate() {
481                    if !self.owns_anything(iface, ty) {
482                        continue;
483                    }
484                    self.free(iface, ty, &format!("&ptr->f{i}"));
485                }
486            }
487
488            TypeDefKind::List(t) => {
489                if self.owns_anything(iface, t) {
490                    self.src.c("for (size_t i = 0; i < ptr->len; i++) {\n");
491                    self.free(iface, t, "&ptr->ptr[i]");
492                    self.src.c("}\n");
493                }
494                uwriteln!(
495                    self.src.c,
496                    "canonical_abi_free(ptr->ptr, ptr->len * {}, {});",
497                    self.sizes.size(t),
498                    self.sizes.align(t),
499                );
500            }
501
502            TypeDefKind::Variant(v) => {
503                self.src.c("switch ((int32_t) ptr->tag) {\n");
504                for (i, case) in v.cases.iter().enumerate() {
505                    if !self.owns_anything(iface, &case.ty) {
506                        continue;
507                    }
508                    uwriteln!(self.src.c, "case {}: {{", i);
509                    let expr = format!("&ptr->val.{}", case.name.to_snake_case());
510                    self.free(iface, &case.ty, &expr);
511                    self.src.c("break;\n");
512                    self.src.c("}\n");
513                }
514                self.src.c("}\n");
515            }
516
517            TypeDefKind::Union(u) => {
518                self.src.c("switch ((int32_t) ptr->tag) {\n");
519                for (i, case) in u.cases.iter().enumerate() {
520                    if !self.owns_anything(iface, &case.ty) {
521                        continue;
522                    }
523                    uwriteln!(self.src.c, "case {i}: {{");
524                    let expr = format!("&ptr->val.f{i}");
525                    self.free(iface, &case.ty, &expr);
526                    self.src.c("break;\n");
527                    self.src.c("}\n");
528                }
529                self.src.c("}\n");
530            }
531
532            TypeDefKind::Option(t) => {
533                self.src.c("if (ptr->is_some) {\n");
534                self.free(iface, t, "&ptr->val");
535                self.src.c("}\n");
536            }
537
538            TypeDefKind::Expected(e) => {
539                self.src.c("if (!ptr->is_err) {\n");
540                if self.owns_anything(iface, &e.ok) {
541                    self.free(iface, &e.ok, "&ptr->val.ok");
542                }
543                if self.owns_anything(iface, &e.err) {
544                    self.src.c("} else {\n");
545                    self.free(iface, &e.err, "&ptr->val.err");
546                }
547                self.src.c("}\n");
548            }
549            TypeDefKind::Future(_) => todo!("print_dtor for future"),
550            TypeDefKind::Stream(_) => todo!("print_dtor for stream"),
551        }
552        self.src.c("}\n");
553    }
554
555    fn owns_anything(&self, iface: &Interface, ty: &Type) -> bool {
556        let id = match ty {
557            Type::Id(id) => *id,
558            Type::String => return true,
559            Type::Handle(_) => return true,
560            _ => return false,
561        };
562        match &iface.types[id].kind {
563            TypeDefKind::Type(t) => self.owns_anything(iface, t),
564            TypeDefKind::Record(r) => r.fields.iter().any(|t| self.owns_anything(iface, &t.ty)),
565            TypeDefKind::Tuple(t) => t.types.iter().any(|t| self.owns_anything(iface, t)),
566            TypeDefKind::Flags(_) => false,
567            TypeDefKind::Enum(_) => false,
568            TypeDefKind::List(_) => true,
569            TypeDefKind::Variant(v) => v.cases.iter().any(|c| self.owns_anything(iface, &c.ty)),
570            TypeDefKind::Union(v) => v
571                .cases
572                .iter()
573                .any(|case| self.owns_anything(iface, &case.ty)),
574            TypeDefKind::Option(t) => self.owns_anything(iface, t),
575            TypeDefKind::Expected(e) => {
576                self.owns_anything(iface, &e.ok) || self.owns_anything(iface, &e.err)
577            }
578            TypeDefKind::Future(_) => todo!("owns_anything for future"),
579            TypeDefKind::Stream(_) => todo!("owns_anything for stream"),
580        }
581    }
582
583    fn free(&mut self, iface: &Interface, ty: &Type, expr: &str) {
584        let prev = mem::take(&mut self.src.h);
585        self.print_namespace(iface);
586        self.print_ty_name(iface, ty);
587        let name = mem::replace(&mut self.src.h, prev);
588
589        self.src.c(&name);
590        self.src.c("_free(");
591        self.src.c(expr);
592        self.src.c(");\n");
593    }
594
595    fn docs(&mut self, docs: &Docs) {
596        let docs = match &docs.contents {
597            Some(docs) => docs,
598            None => return,
599        };
600        for line in docs.trim().lines() {
601            self.src.h("// ");
602            self.src.h(line);
603            self.src.h("\n");
604        }
605    }
606}
607
608impl Return {
609    fn return_single(&mut self, iface: &Interface, ty: &Type, orig_ty: &Type) {
610        let id = match ty {
611            Type::Id(id) => *id,
612            Type::String => {
613                self.retptrs.push(*orig_ty);
614                return;
615            }
616            Type::Unit => {
617                self.scalar = Some(Scalar::Void);
618                return;
619            }
620            _ => {
621                self.scalar = Some(Scalar::Type(*orig_ty));
622                return;
623            }
624        };
625        match &iface.types[id].kind {
626            TypeDefKind::Type(t) => self.return_single(iface, t, orig_ty),
627
628            // Flags are returned as their bare values
629            TypeDefKind::Flags(_) => {
630                self.scalar = Some(Scalar::Type(*orig_ty));
631            }
632
633            // Tuples get splatted to multiple return pointers
634            TypeDefKind::Tuple(_) => self.splat_tuples(iface, ty, orig_ty),
635
636            // Record returns are always through a pointer
637            TypeDefKind::Record(_) => {
638                self.retptrs.push(*orig_ty);
639            }
640
641            // other records/lists/buffers always go to return pointers
642            TypeDefKind::List(_) => self.retptrs.push(*orig_ty),
643
644            // Enums are scalars
645            TypeDefKind::Enum(_) => {
646                self.scalar = Some(Scalar::Type(*orig_ty));
647            }
648
649            // Unpack optional returns where a boolean discriminant is
650            // returned and then the actual type returned is returned
651            // through a return pointer.
652            TypeDefKind::Option(ty) => {
653                self.scalar = Some(Scalar::OptionBool(*ty));
654                self.retptrs.push(*ty);
655            }
656
657            // Unpack `expected<T, E>` returns where `E` looks like an enum
658            // so we can return that in the scalar return and have `T` get
659            // returned through the normal returns.
660            TypeDefKind::Expected(e) => {
661                if let Type::Id(err) = e.err {
662                    if let TypeDefKind::Enum(enum_) = &iface.types[err].kind {
663                        self.scalar = Some(Scalar::ExpectedEnum {
664                            err,
665                            max_err: enum_.cases.len(),
666                        });
667                        self.splat_tuples(iface, &e.ok, &e.ok);
668                        return;
669                    }
670                }
671
672                // otherwise just return the variant via a normal
673                // return pointer
674                self.retptrs.push(*orig_ty);
675            }
676
677            TypeDefKind::Variant(_) | TypeDefKind::Union(_) => {
678                self.retptrs.push(*orig_ty);
679            }
680            TypeDefKind::Future(_) => todo!("return_single for future"),
681            TypeDefKind::Stream(_) => todo!("return_single for stream"),
682        }
683    }
684
685    fn splat_tuples(&mut self, iface: &Interface, ty: &Type, orig_ty: &Type) {
686        let id = match ty {
687            Type::Id(id) => *id,
688            Type::Unit => return,
689            _ => {
690                self.retptrs.push(*orig_ty);
691                return;
692            }
693        };
694        match &iface.types[id].kind {
695            TypeDefKind::Tuple(t) => {
696                self.splat_tuple = true;
697                self.retptrs.extend(t.types.iter());
698            }
699            _ => self.retptrs.push(*orig_ty),
700        }
701    }
702}
703
704impl Generator for C {
705    fn preprocess_one(&mut self, iface: &Interface, dir: Direction) {
706        let variant = Self::abi_variant(dir);
707        self.sizes.fill(iface);
708        self.in_import = variant == AbiVariant::GuestImport;
709    }
710
711    fn type_record(
712        &mut self,
713        iface: &Interface,
714        id: TypeId,
715        name: &str,
716        record: &Record,
717        docs: &Docs,
718    ) {
719        let prev = mem::take(&mut self.src.h);
720        self.docs(docs);
721        self.names.insert(&name.to_snake_case()).unwrap();
722        self.src.h("typedef struct {\n");
723        for field in record.fields.iter() {
724            self.print_ty(iface, &field.ty);
725            self.src.h(" ");
726            self.src.h(&field.name.to_snake_case());
727            self.src.h(";\n");
728        }
729        self.src.h("} ");
730        self.print_namespace(iface);
731        self.src.h(&name.to_snake_case());
732        self.src.h("_t;\n");
733
734        self.types.insert(id, mem::replace(&mut self.src.h, prev));
735    }
736
737    fn type_tuple(
738        &mut self,
739        iface: &Interface,
740        id: TypeId,
741        name: &str,
742        tuple: &Tuple,
743        docs: &Docs,
744    ) {
745        let prev = mem::take(&mut self.src.h);
746        self.docs(docs);
747        self.names.insert(&name.to_snake_case()).unwrap();
748        self.src.h("typedef struct {\n");
749        for (i, ty) in tuple.types.iter().enumerate() {
750            self.print_ty(iface, ty);
751            uwriteln!(self.src.h, " f{i};");
752        }
753        self.src.h("} ");
754        self.print_namespace(iface);
755        self.src.h(&name.to_snake_case());
756        self.src.h("_t;\n");
757
758        self.types.insert(id, mem::replace(&mut self.src.h, prev));
759    }
760
761    fn type_flags(
762        &mut self,
763        iface: &Interface,
764        id: TypeId,
765        name: &str,
766        flags: &Flags,
767        docs: &Docs,
768    ) {
769        let prev = mem::take(&mut self.src.h);
770        self.docs(docs);
771        self.names.insert(&name.to_snake_case()).unwrap();
772        self.src.h("typedef ");
773        let repr = flags_repr(flags);
774        self.src.h(int_repr(repr));
775        self.src.h(" ");
776        self.print_namespace(iface);
777        self.src.h(&name.to_snake_case());
778        self.src.h("_t;\n");
779
780        for (i, flag) in flags.flags.iter().enumerate() {
781            uwriteln!(
782                self.src.h,
783                "#define {}_{}_{} (1 << {})",
784                iface.name.to_shouty_snake_case(),
785                name.to_shouty_snake_case(),
786                flag.name.to_shouty_snake_case(),
787                i,
788            );
789        }
790
791        self.types.insert(id, mem::replace(&mut self.src.h, prev));
792    }
793
794    fn type_variant(
795        &mut self,
796        iface: &Interface,
797        id: TypeId,
798        name: &str,
799        variant: &Variant,
800        docs: &Docs,
801    ) {
802        let prev = mem::take(&mut self.src.h);
803        self.docs(docs);
804        self.names.insert(&name.to_snake_case()).unwrap();
805        self.src.h("typedef struct {\n");
806        self.src.h(int_repr(variant.tag()));
807        self.src.h(" tag;\n");
808        self.src.h("union {\n");
809        for case in variant.cases.iter() {
810            if self.is_empty_type(iface, &case.ty) {
811                continue;
812            }
813            self.print_ty(iface, &case.ty);
814            self.src.h(" ");
815            self.src.h(&case.name.to_snake_case());
816            self.src.h(";\n");
817        }
818        self.src.h("} val;\n");
819        self.src.h("} ");
820        self.print_namespace(iface);
821        self.src.h(&name.to_snake_case());
822        self.src.h("_t;\n");
823        for (i, case) in variant.cases.iter().enumerate() {
824            uwriteln!(
825                self.src.h,
826                "#define {}_{}_{} {}",
827                iface.name.to_shouty_snake_case(),
828                name.to_shouty_snake_case(),
829                case.name.to_shouty_snake_case(),
830                i,
831            );
832        }
833
834        self.types.insert(id, mem::replace(&mut self.src.h, prev));
835    }
836
837    fn type_union(
838        &mut self,
839        iface: &Interface,
840        id: TypeId,
841        name: &str,
842        union: &Union,
843        docs: &Docs,
844    ) {
845        let prev = mem::take(&mut self.src.h);
846        self.docs(docs);
847        self.names.insert(&name.to_snake_case()).unwrap();
848        self.src.h("typedef struct {\n");
849        self.src.h(int_repr(union.tag()));
850        self.src.h(" tag;\n");
851        self.src.h("union {\n");
852        for (i, case) in union.cases.iter().enumerate() {
853            self.print_ty(iface, &case.ty);
854            uwriteln!(self.src.h, " f{i};");
855        }
856        self.src.h("} val;\n");
857        self.src.h("} ");
858        self.print_namespace(iface);
859        self.src.h(&name.to_snake_case());
860        self.src.h("_t;\n");
861
862        self.types.insert(id, mem::replace(&mut self.src.h, prev));
863    }
864
865    fn type_option(
866        &mut self,
867        iface: &Interface,
868        id: TypeId,
869        name: &str,
870        payload: &Type,
871        docs: &Docs,
872    ) {
873        let prev = mem::take(&mut self.src.h);
874        self.docs(docs);
875        self.names.insert(&name.to_snake_case()).unwrap();
876        self.src.h("typedef struct {\n");
877        self.src.h("bool is_some;\n");
878        if !self.is_empty_type(iface, payload) {
879            self.print_ty(iface, payload);
880            self.src.h(" val;\n");
881        }
882        self.src.h("} ");
883        self.print_namespace(iface);
884        self.src.h(&name.to_snake_case());
885        self.src.h("_t;\n");
886
887        self.types.insert(id, mem::replace(&mut self.src.h, prev));
888    }
889
890    fn type_expected(
891        &mut self,
892        iface: &Interface,
893        id: TypeId,
894        name: &str,
895        expected: &Expected,
896        docs: &Docs,
897    ) {
898        let prev = mem::take(&mut self.src.h);
899        self.docs(docs);
900        self.names.insert(&name.to_snake_case()).unwrap();
901        self.src.h("typedef struct {\n");
902        self.src.h("bool is_err;\n");
903        self.src.h("union {\n");
904        if !self.is_empty_type(iface, &expected.ok) {
905            self.print_ty(iface, &expected.ok);
906            self.src.h(" ok;\n");
907        }
908        if !self.is_empty_type(iface, &expected.err) {
909            self.print_ty(iface, &expected.err);
910            self.src.h(" err;\n");
911        }
912        self.src.h("} val;\n");
913        self.src.h("} ");
914        self.print_namespace(iface);
915        self.src.h(&name.to_snake_case());
916        self.src.h("_t;\n");
917
918        self.types.insert(id, mem::replace(&mut self.src.h, prev));
919    }
920
921    fn type_enum(&mut self, iface: &Interface, id: TypeId, name: &str, enum_: &Enum, docs: &Docs) {
922        let prev = mem::take(&mut self.src.h);
923        self.docs(docs);
924        self.names.insert(&name.to_snake_case()).unwrap();
925        self.src.h("typedef ");
926        self.src.h(int_repr(enum_.tag()));
927        self.src.h(" ");
928        self.print_namespace(iface);
929        self.src.h(&name.to_snake_case());
930        self.src.h("_t;\n");
931        for (i, case) in enum_.cases.iter().enumerate() {
932            uwriteln!(
933                self.src.h,
934                "#define {}_{}_{} {}",
935                iface.name.to_shouty_snake_case(),
936                name.to_shouty_snake_case(),
937                case.name.to_shouty_snake_case(),
938                i,
939            );
940        }
941
942        self.types.insert(id, mem::replace(&mut self.src.h, prev));
943    }
944
945    fn type_resource(&mut self, iface: &Interface, ty: ResourceId) {
946        drop((iface, ty));
947    }
948
949    fn type_alias(&mut self, iface: &Interface, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
950        let prev = mem::take(&mut self.src.h);
951        self.docs(docs);
952        self.src.h("typedef ");
953        self.print_ty(iface, ty);
954        self.src.h(" ");
955        self.print_namespace(iface);
956        self.src.h(&name.to_snake_case());
957        self.src.h("_t;\n");
958        self.types.insert(id, mem::replace(&mut self.src.h, prev));
959    }
960
961    fn type_list(&mut self, iface: &Interface, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
962        let prev = mem::take(&mut self.src.h);
963        self.docs(docs);
964        self.src.h("typedef struct {\n");
965        self.print_ty(iface, ty);
966        self.src.h(" *ptr;\n");
967        self.src.h("size_t len;\n");
968        self.src.h("} ");
969        self.print_namespace(iface);
970        self.src.h(&name.to_snake_case());
971        self.src.h("_t;\n");
972        self.types.insert(id, mem::replace(&mut self.src.h, prev));
973    }
974
975    fn type_builtin(&mut self, iface: &Interface, _id: TypeId, name: &str, ty: &Type, docs: &Docs) {
976        drop((iface, _id, name, ty, docs));
977    }
978
979    fn import(&mut self, iface: &Interface, func: &Function) {
980        assert!(!func.is_async, "async not supported yet");
981        let prev = mem::take(&mut self.src);
982        let sig = iface.wasm_signature(AbiVariant::GuestImport, func);
983
984        // In the private C file, print a function declaration which is the
985        // actual wasm import that we'll be calling, and this has the raw wasm
986        // signature.
987        uwriteln!(
988            self.src.c,
989            "__attribute__((import_module(\"{}\"), import_name(\"{}\")))",
990            iface.name,
991            func.name
992        );
993        let import_name = self.names.tmp(&format!(
994            "__wasm_import_{}_{}",
995            iface.name.to_snake_case(),
996            func.name.to_snake_case()
997        ));
998        match sig.results.len() {
999            0 => self.src.c("void"),
1000            1 => self.src.c(wasm_type(sig.results[0])),
1001            _ => unimplemented!("multi-value return not supported"),
1002        }
1003        self.src.c(" ");
1004        self.src.c(&import_name);
1005        self.src.c("(");
1006        for (i, param) in sig.params.iter().enumerate() {
1007            if i > 0 {
1008                self.src.c(", ");
1009            }
1010            self.src.c(wasm_type(*param));
1011        }
1012        if sig.params.len() == 0 {
1013            self.src.c("void");
1014        }
1015        self.src.c(");\n");
1016
1017        // Print the public facing signature into the header, and since that's
1018        // what we are defining also print it into the C file.
1019        let c_sig = self.print_sig(iface, func);
1020        self.src.c(&c_sig.sig);
1021        self.src.c(" {\n");
1022
1023        let mut f = FunctionBindgen::new(self, c_sig, &import_name);
1024        for (pointer, param) in f.sig.params.iter() {
1025            f.locals.insert(param).unwrap();
1026
1027            if *pointer {
1028                f.params.push(format!("*{}", param));
1029            } else {
1030                f.params.push(param.clone());
1031            }
1032        }
1033        for ptr in f.sig.retptrs.iter() {
1034            f.locals.insert(ptr).unwrap();
1035        }
1036        iface.call(
1037            AbiVariant::GuestImport,
1038            LiftLower::LowerArgsLiftResults,
1039            func,
1040            &mut f,
1041        );
1042
1043        let FunctionBindgen { src, .. } = f;
1044
1045        self.src.c(&String::from(src));
1046        self.src.c("}\n");
1047
1048        let src = mem::replace(&mut self.src, prev);
1049        self.funcs
1050            .entry(iface.name.to_string())
1051            .or_insert(Vec::new())
1052            .push(Func { src });
1053    }
1054
1055    fn export(&mut self, iface: &Interface, func: &Function) {
1056        assert!(!func.is_async, "async not supported yet");
1057        let prev = mem::take(&mut self.src);
1058        let sig = iface.wasm_signature(AbiVariant::GuestExport, func);
1059
1060        // Print the actual header for this function into the header file, and
1061        // it's what we'll be calling.
1062        let c_sig = self.print_sig(iface, func);
1063
1064        // Generate, in the C source file, the raw wasm signature that has the
1065        // canonical ABI.
1066        uwriteln!(
1067            self.src.c,
1068            "__attribute__((export_name(\"{}\")))",
1069            func.name
1070        );
1071        let import_name = self.names.tmp(&format!(
1072            "__wasm_export_{}_{}",
1073            iface.name.to_snake_case(),
1074            func.name.to_snake_case()
1075        ));
1076
1077        let mut f = FunctionBindgen::new(self, c_sig, &import_name);
1078        match sig.results.len() {
1079            0 => f.gen.src.c("void"),
1080            1 => f.gen.src.c(wasm_type(sig.results[0])),
1081            _ => unimplemented!("multi-value return not supported"),
1082        }
1083        f.gen.src.c(" ");
1084        f.gen.src.c(&import_name);
1085        f.gen.src.c("(");
1086        for (i, param) in sig.params.iter().enumerate() {
1087            if i > 0 {
1088                f.gen.src.c(", ");
1089            }
1090            let name = f.locals.tmp("arg");
1091            uwrite!(f.gen.src.c, "{} {}", wasm_type(*param), name);
1092            f.params.push(name);
1093        }
1094        if sig.params.len() == 0 {
1095            f.gen.src.c("void");
1096        }
1097        f.gen.src.c(") {\n");
1098
1099        // Perform all lifting/lowering and append it to our src.
1100        iface.call(
1101            AbiVariant::GuestExport,
1102            LiftLower::LiftArgsLowerResults,
1103            func,
1104            &mut f,
1105        );
1106        let FunctionBindgen { src, .. } = f;
1107        self.src.c(&src);
1108        self.src.c("}\n");
1109
1110        let src = mem::replace(&mut self.src, prev);
1111        self.funcs
1112            .entry(iface.name.to_string())
1113            .or_insert(Vec::new())
1114            .push(Func { src });
1115    }
1116
1117    fn finish_one(&mut self, iface: &Interface, files: &mut Files) {
1118        uwrite!(
1119            self.src.h,
1120            "\
1121                #ifndef __BINDINGS_{0}_H
1122                #define __BINDINGS_{0}_H
1123                #ifdef __cplusplus
1124                extern \"C\"
1125                {{
1126                #endif
1127
1128                #include <stdint.h>
1129                #include <stdbool.h>
1130            ",
1131            iface.name.to_shouty_snake_case(),
1132        );
1133        uwrite!(
1134            self.src.c,
1135            "\
1136                #include <stdlib.h>
1137                #include <{}.h>
1138            ",
1139            iface.name.to_kebab_case(),
1140        );
1141
1142        self.print_intrinsics();
1143
1144        for (_, resource) in iface.resources.iter() {
1145            let ns = iface.name.to_snake_case();
1146            let name = resource.name.to_snake_case();
1147            uwrite!(
1148                self.src.h,
1149                "
1150                    typedef struct {{
1151                        uint32_t idx;
1152                    }} {ns}_{name}_t;
1153                    void {ns}_{name}_free({ns}_{name}_t *ptr);
1154                    {ns}_{name}_t {ns}_{name}_clone({ns}_{name}_t *ptr);
1155                ",
1156                ns = ns,
1157                name = name,
1158            );
1159            uwrite!(
1160                self.src.c,
1161                "
1162                    __attribute__((import_module(\"canonical_abi\"), import_name(\"resource_drop_{name_orig}\")))
1163                    void __resource_{name}_drop(uint32_t idx);
1164
1165                    void {ns}_{name}_free({ns}_{name}_t *ptr) {{
1166                        __resource_{name}_drop(ptr->idx);
1167                    }}
1168
1169                    __attribute__((import_module(\"canonical_abi\"), import_name(\"resource_clone_{name_orig}\")))
1170                    uint32_t __resource_{name}_clone(uint32_t idx);
1171
1172                    {ns}_{name}_t {ns}_{name}_clone({ns}_{name}_t *ptr) {{
1173                        return ({ns}_{name}_t){{__resource_{name}_clone(ptr->idx)}};
1174                    }}
1175                ",
1176                ns = ns,
1177                name = name,
1178                name_orig = resource.name,
1179            );
1180
1181            // Exported resources have more capabilities, they can create new
1182            // resources and get the private value that it was created with.
1183            // Furthermore we also define the destructor which delegates to the
1184            // actual user-defined destructor, if any.
1185            if !self.in_import {
1186                uwrite!(
1187                    self.src.h,
1188                    "\
1189                        {ns}_{name}_t {ns}_{name}_new(void *data);
1190                        void* {ns}_{name}_get({ns}_{name}_t *ptr);
1191
1192                        __attribute__((weak))
1193                        void {ns}_{name}_dtor(void *data);
1194                    ",
1195                    ns = ns,
1196                    name = name,
1197                );
1198                uwrite!(
1199                    self.src.c,
1200                    "
1201                        __attribute__((import_module(\"canonical_abi\"), import_name(\"resource_new_{name_orig}\")))
1202                        uint32_t __resource_{name}_new(uint32_t val);
1203
1204                        {ns}_{name}_t {ns}_{name}_new(void *data) {{
1205                            return ({ns}_{name}_t){{__resource_{name}_new((uint32_t) data)}};
1206                        }}
1207
1208                        __attribute__((import_module(\"canonical_abi\"), import_name(\"resource_get_{name_orig}\")))
1209                        uint32_t __resource_{name}_get(uint32_t idx);
1210
1211                        void* {ns}_{name}_get({ns}_{name}_t *ptr) {{
1212                            return (void*) __resource_{name}_get(ptr->idx);
1213                        }}
1214
1215                        __attribute__((export_name(\"canonical_abi_drop_{name_orig}\")))
1216                        void __resource_{name}_dtor(uint32_t val) {{
1217                            if ({ns}_{name}_dtor)
1218                                {ns}_{name}_dtor((void*) val);
1219                        }}
1220                    ",
1221                    ns = ns,
1222                    name = name,
1223                    name_orig = resource.name,
1224                );
1225            }
1226        }
1227
1228        // Continuously generate anonymous types while we continue to find more
1229        //
1230        // First we take care of the public set of anonymous types. This will
1231        // iteratively print them and also remove any references from the
1232        // private set if we happen to also reference them.
1233        while !self.public_anonymous_types.is_empty() {
1234            for ty in mem::take(&mut self.public_anonymous_types) {
1235                self.print_anonymous_type(iface, ty);
1236            }
1237        }
1238
1239        // Next we take care of private types. To do this we have basically the
1240        // same loop as above, after we switch the sets. We record, however,
1241        // all private types in a local set here to later determine if the type
1242        // needs to be in the C file or the H file.
1243        //
1244        // Note though that we don't re-print a type (and consider it private)
1245        // if we already printed it above as part of the public set.
1246        let mut private_types = HashSet::new();
1247        self.public_anonymous_types = mem::take(&mut self.private_anonymous_types);
1248        while !self.public_anonymous_types.is_empty() {
1249            for ty in mem::take(&mut self.public_anonymous_types) {
1250                if self.types.contains_key(&ty) {
1251                    continue;
1252                }
1253                private_types.insert(ty);
1254                self.print_anonymous_type(iface, ty);
1255            }
1256        }
1257
1258        if self.needs_string {
1259            uwrite!(
1260                self.src.h,
1261                "
1262                    typedef struct {{
1263                        char *ptr;
1264                        size_t len;
1265                    }} {0}_string_t;
1266
1267                    void {0}_string_set({0}_string_t *ret, const char *s);
1268                    void {0}_string_dup({0}_string_t *ret, const char *s);
1269                    void {0}_string_free({0}_string_t *ret);
1270                ",
1271                iface.name.to_snake_case(),
1272            );
1273            self.src.c("#include <string.h>\n");
1274            uwrite!(
1275                self.src.c,
1276                "
1277                    void {0}_string_set({0}_string_t *ret, const char *s) {{
1278                        ret->ptr = (char*) s;
1279                        ret->len = strlen(s);
1280                    }}
1281
1282                    void {0}_string_dup({0}_string_t *ret, const char *s) {{
1283                        ret->len = strlen(s);
1284                        ret->ptr = canonical_abi_realloc(NULL, 0, 1, ret->len);
1285                        memcpy(ret->ptr, s, ret->len);
1286                    }}
1287
1288                    void {0}_string_free({0}_string_t *ret) {{
1289                        canonical_abi_free(ret->ptr, ret->len, 1);
1290                        ret->ptr = NULL;
1291                        ret->len = 0;
1292                    }}
1293                ",
1294                iface.name.to_snake_case(),
1295            );
1296        }
1297
1298        // Afterwards print all types. Note that this print must be in a
1299        // topological order, so we
1300        for id in iface.topological_types() {
1301            if let Some(ty) = self.types.get(&id) {
1302                if private_types.contains(&id) {
1303                    self.src.c(ty);
1304                } else {
1305                    self.src.h(ty);
1306                    self.print_dtor(iface, id);
1307                }
1308            }
1309        }
1310
1311        if self.return_pointer_area_size > 0 {
1312            uwrite!(
1313                self.src.c,
1314                "
1315                    __attribute__((aligned({})))
1316                    static uint8_t RET_AREA[{}];
1317                ",
1318                self.return_pointer_area_align,
1319                self.return_pointer_area_size,
1320            );
1321        }
1322
1323        for (_module, funcs) in mem::take(&mut self.funcs) {
1324            for func in funcs {
1325                self.src.h(&func.src.h);
1326                self.src.c(&func.src.c);
1327            }
1328        }
1329
1330        self.src.h("\
1331        #ifdef __cplusplus
1332        }
1333        #endif
1334        ");
1335        self.src.h("#endif\n");
1336
1337        files.push(
1338            &format!("{}.c", iface.name.to_kebab_case()),
1339            self.src.c.as_bytes(),
1340        );
1341        files.push(
1342            &format!("{}.h", iface.name.to_kebab_case()),
1343            self.src.h.as_bytes(),
1344        );
1345    }
1346}
1347
1348struct FunctionBindgen<'a> {
1349    gen: &'a mut C,
1350    locals: Ns,
1351    // tmp: usize,
1352    src: wai_bindgen_gen_core::Source,
1353    sig: CSig,
1354    func_to_call: &'a str,
1355    block_storage: Vec<wai_bindgen_gen_core::Source>,
1356    blocks: Vec<(String, Vec<String>)>,
1357    payloads: Vec<String>,
1358    params: Vec<String>,
1359    wasm_return: Option<String>,
1360}
1361
1362impl<'a> FunctionBindgen<'a> {
1363    fn new(gen: &'a mut C, sig: CSig, func_to_call: &'a str) -> FunctionBindgen<'a> {
1364        FunctionBindgen {
1365            gen,
1366            sig,
1367            locals: Default::default(),
1368            src: Default::default(),
1369            func_to_call,
1370            block_storage: Vec::new(),
1371            blocks: Vec::new(),
1372            payloads: Vec::new(),
1373            params: Vec::new(),
1374            wasm_return: None,
1375        }
1376    }
1377
1378    fn store_op(&mut self, op: &str, loc: &str) {
1379        self.src.push_str(loc);
1380        self.src.push_str(" = ");
1381        self.src.push_str(op);
1382        self.src.push_str(";\n");
1383    }
1384
1385    fn load(&mut self, ty: &str, offset: i32, operands: &[String], results: &mut Vec<String>) {
1386        results.push(format!("*(({}*) ({} + {}))", ty, operands[0], offset));
1387    }
1388
1389    fn load_ext(&mut self, ty: &str, offset: i32, operands: &[String], results: &mut Vec<String>) {
1390        self.load(ty, offset, operands, results);
1391        let result = results.pop().unwrap();
1392        results.push(format!("(int32_t) ({})", result));
1393    }
1394
1395    fn store(&mut self, ty: &str, offset: i32, operands: &[String]) {
1396        uwriteln!(
1397            self.src,
1398            "*(({}*)({} + {})) = {};",
1399            ty,
1400            operands[1],
1401            offset,
1402            operands[0]
1403        );
1404    }
1405
1406    fn store_in_retptrs(&mut self, operands: &[String]) {
1407        if self.sig.ret.splat_tuple {
1408            assert_eq!(operands.len(), 1);
1409            let op = &operands[0];
1410            for (i, ptr) in self.sig.retptrs.clone().into_iter().enumerate() {
1411                self.store_op(&format!("{}.f{}", op, i), &format!("*{}", ptr));
1412            }
1413            // ...
1414        } else {
1415            assert_eq!(operands.len(), self.sig.retptrs.len());
1416            for (op, ptr) in operands.iter().zip(self.sig.retptrs.clone()) {
1417                self.store_op(op, &format!("*{}", ptr));
1418            }
1419        }
1420    }
1421}
1422
1423impl Bindgen for FunctionBindgen<'_> {
1424    type Operand = String;
1425
1426    fn sizes(&self) -> &SizeAlign {
1427        &self.gen.sizes
1428    }
1429
1430    fn push_block(&mut self) {
1431        let prev = mem::take(&mut self.src);
1432        self.block_storage.push(prev);
1433    }
1434
1435    fn finish_block(&mut self, operands: &mut Vec<String>) {
1436        let to_restore = self.block_storage.pop().unwrap();
1437        let src = mem::replace(&mut self.src, to_restore);
1438        self.blocks.push((src.into(), mem::take(operands)));
1439    }
1440
1441    fn return_pointer(&mut self, _iface: &Interface, size: usize, align: usize) -> String {
1442        self.gen.return_pointer_area_size = self.gen.return_pointer_area_size.max(size);
1443        self.gen.return_pointer_area_align = self.gen.return_pointer_area_align.max(align);
1444        let ptr = self.locals.tmp("ptr");
1445        uwriteln!(self.src, "int32_t {} = (int32_t) &RET_AREA;", ptr);
1446        ptr
1447    }
1448
1449    fn is_list_canonical(&self, iface: &Interface, ty: &Type) -> bool {
1450        iface.all_bits_valid(ty)
1451    }
1452
1453    fn emit(
1454        &mut self,
1455        iface: &Interface,
1456        inst: &Instruction<'_>,
1457        operands: &mut Vec<String>,
1458        results: &mut Vec<String>,
1459    ) {
1460        match inst {
1461            Instruction::GetArg { nth } => results.push(self.params[*nth].clone()),
1462            Instruction::I32Const { val } => results.push(val.to_string()),
1463            Instruction::ConstZero { tys } => {
1464                for _ in tys.iter() {
1465                    results.push("0".to_string());
1466                }
1467            }
1468
1469            // TODO: checked?
1470            Instruction::U8FromI32 => results.push(format!("(uint8_t) ({})", operands[0])),
1471            Instruction::S8FromI32 => results.push(format!("(int8_t) ({})", operands[0])),
1472            Instruction::U16FromI32 => results.push(format!("(uint16_t) ({})", operands[0])),
1473            Instruction::S16FromI32 => results.push(format!("(int16_t) ({})", operands[0])),
1474            Instruction::U32FromI32 => results.push(format!("(uint32_t) ({})", operands[0])),
1475            Instruction::S32FromI32 | Instruction::S64FromI64 => results.push(operands[0].clone()),
1476            Instruction::U64FromI64 => results.push(format!("(uint64_t) ({})", operands[0])),
1477
1478            Instruction::I32FromU8
1479            | Instruction::I32FromS8
1480            | Instruction::I32FromU16
1481            | Instruction::I32FromS16
1482            | Instruction::I32FromU32 => {
1483                results.push(format!("(int32_t) ({})", operands[0]));
1484            }
1485            Instruction::I32FromS32 | Instruction::I64FromS64 => results.push(operands[0].clone()),
1486            Instruction::I64FromU64 => {
1487                results.push(format!("(int64_t) ({})", operands[0]));
1488            }
1489
1490            // f32/f64 have the same representation in the import type and in C,
1491            // so no conversions necessary.
1492            Instruction::F32FromFloat32
1493            | Instruction::F64FromFloat64
1494            | Instruction::Float32FromF32
1495            | Instruction::Float64FromF64 => {
1496                results.push(operands[0].clone());
1497            }
1498
1499            // TODO: checked
1500            Instruction::CharFromI32 => {
1501                results.push(format!("(uint32_t) ({})", operands[0]));
1502            }
1503            Instruction::I32FromChar => {
1504                results.push(format!("(int32_t) ({})", operands[0]));
1505            }
1506
1507            Instruction::Bitcasts { casts } => {
1508                for (cast, op) in casts.iter().zip(operands) {
1509                    let op = op;
1510                    match cast {
1511                        Bitcast::I32ToF32 | Bitcast::I64ToF32 => {
1512                            results
1513                                .push(format!("((union {{ int32_t a; float b; }}){{ {} }}).b", op));
1514                        }
1515                        Bitcast::F32ToI32 | Bitcast::F32ToI64 => {
1516                            results
1517                                .push(format!("((union {{ float a; int32_t b; }}){{ {} }}).b", op));
1518                        }
1519                        Bitcast::I64ToF64 => {
1520                            results.push(format!(
1521                                "((union {{ int64_t a; double b; }}){{ {} }}).b",
1522                                op
1523                            ));
1524                        }
1525                        Bitcast::F64ToI64 => {
1526                            results.push(format!(
1527                                "((union {{ double a; int64_t b; }}){{ {} }}).b",
1528                                op
1529                            ));
1530                        }
1531                        Bitcast::I32ToI64 => {
1532                            results.push(format!("(int64_t) {}", op));
1533                        }
1534                        Bitcast::I64ToI32 => {
1535                            results.push(format!("(int32_t) {}", op));
1536                        }
1537                        Bitcast::None => results.push(op.to_string()),
1538                    }
1539                }
1540            }
1541
1542            Instruction::UnitLower => {}
1543            Instruction::UnitLift => {
1544                results.push("INVALID".to_string());
1545            }
1546            Instruction::BoolFromI32 | Instruction::I32FromBool => {
1547                results.push(operands[0].clone());
1548            }
1549
1550            Instruction::I32FromOwnedHandle { .. } | Instruction::I32FromBorrowedHandle { .. } => {
1551                results.push(format!("({}).idx", operands[0]));
1552            }
1553
1554            Instruction::HandleBorrowedFromI32 { ty, .. }
1555            | Instruction::HandleOwnedFromI32 { ty, .. } => {
1556                results.push(format!(
1557                    "({}_{}_t){{ {} }}",
1558                    iface.name.to_snake_case(),
1559                    iface.resources[*ty].name.to_snake_case(),
1560                    operands[0],
1561                ));
1562            }
1563
1564            Instruction::RecordLower { record, .. } => {
1565                let op = &operands[0];
1566                for f in record.fields.iter() {
1567                    results.push(format!("({}).{}", op, f.name.to_snake_case()));
1568                }
1569            }
1570            Instruction::RecordLift { ty, .. } => {
1571                let name = self.gen.type_string(iface, &Type::Id(*ty));
1572                let mut result = format!("({}) {{\n", name);
1573                for op in operands {
1574                    uwriteln!(result, "{},", op);
1575                }
1576                result.push_str("}");
1577                results.push(result);
1578            }
1579
1580            Instruction::TupleLower { tuple, .. } => {
1581                let op = &operands[0];
1582                for i in 0..tuple.types.len() {
1583                    results.push(format!("({}).f{}", op, i));
1584                }
1585            }
1586            Instruction::TupleLift { ty, .. } => {
1587                let name = self.gen.type_string(iface, &Type::Id(*ty));
1588                let mut result = format!("({}) {{\n", name);
1589                for op in operands {
1590                    uwriteln!(result, "{},", op);
1591                }
1592                result.push_str("}");
1593                results.push(result);
1594            }
1595
1596            // TODO: checked
1597            Instruction::FlagsLower { flags, ty, .. } => match flags_repr(flags) {
1598                Int::U8 | Int::U16 | Int::U32 => {
1599                    results.push(operands.pop().unwrap());
1600                }
1601                Int::U64 => {
1602                    let name = self.gen.type_string(iface, &Type::Id(*ty));
1603                    let tmp = self.locals.tmp("flags");
1604                    uwriteln!(self.src, "{name} {tmp} = {};", operands[0]);
1605                    results.push(format!("{tmp} & 0xffffffff"));
1606                    results.push(format!("({tmp} >> 32) & 0xffffffff"));
1607                }
1608            },
1609
1610            Instruction::FlagsLift { flags, ty, .. } => match flags_repr(flags) {
1611                Int::U8 | Int::U16 | Int::U32 => {
1612                    results.push(operands.pop().unwrap());
1613                }
1614                Int::U64 => {
1615                    let name = self.gen.type_string(iface, &Type::Id(*ty));
1616                    let op0 = &operands[0];
1617                    let op1 = &operands[1];
1618                    results.push(format!("(({name}) ({op0})) | ((({name}) ({op1})) << 32)"));
1619                }
1620            },
1621
1622            Instruction::VariantPayloadName => {
1623                let name = self.locals.tmp("payload");
1624                results.push(format!("*{}", name));
1625                self.payloads.push(name);
1626            }
1627
1628            Instruction::VariantLower {
1629                variant,
1630                results: result_types,
1631                ..
1632            } => {
1633                let blocks = self
1634                    .blocks
1635                    .drain(self.blocks.len() - variant.cases.len()..)
1636                    .collect::<Vec<_>>();
1637                let payloads = self
1638                    .payloads
1639                    .drain(self.payloads.len() - variant.cases.len()..)
1640                    .collect::<Vec<_>>();
1641
1642                let mut variant_results = Vec::with_capacity(result_types.len());
1643                for ty in result_types.iter() {
1644                    let name = self.locals.tmp("variant");
1645                    results.push(name.clone());
1646                    self.src.push_str(wasm_type(*ty));
1647                    self.src.push_str(" ");
1648                    self.src.push_str(&name);
1649                    self.src.push_str(";\n");
1650                    variant_results.push(name);
1651                }
1652
1653                let expr_to_match = format!("({}).tag", operands[0]);
1654
1655                uwriteln!(self.src, "switch ((int32_t) {}) {{", expr_to_match);
1656                for (i, ((case, (block, block_results)), payload)) in
1657                    variant.cases.iter().zip(blocks).zip(payloads).enumerate()
1658                {
1659                    uwriteln!(self.src, "case {}: {{", i);
1660                    if !self.gen.is_empty_type(iface, &case.ty) {
1661                        let ty = self.gen.type_string(iface, &case.ty);
1662                        uwrite!(
1663                            self.src,
1664                            "const {} *{} = &({}).val",
1665                            ty,
1666                            payload,
1667                            operands[0],
1668                        );
1669                        self.src.push_str(".");
1670                        self.src.push_str(&case.name.to_snake_case());
1671                        self.src.push_str(";\n");
1672                    }
1673                    self.src.push_str(&block);
1674
1675                    for (name, result) in variant_results.iter().zip(&block_results) {
1676                        uwriteln!(self.src, "{} = {};", name, result);
1677                    }
1678                    self.src.push_str("break;\n}\n");
1679                }
1680                self.src.push_str("}\n");
1681            }
1682
1683            Instruction::VariantLift { variant, ty, .. } => {
1684                let blocks = self
1685                    .blocks
1686                    .drain(self.blocks.len() - variant.cases.len()..)
1687                    .collect::<Vec<_>>();
1688
1689                let ty = self.gen.type_string(iface, &Type::Id(*ty));
1690                let result = self.locals.tmp("variant");
1691                uwriteln!(self.src, "{} {};", ty, result);
1692                uwriteln!(self.src, "{}.tag = {};", result, operands[0]);
1693                uwriteln!(self.src, "switch ((int32_t) {}.tag) {{", result);
1694                for (i, (case, (block, block_results))) in
1695                    variant.cases.iter().zip(blocks).enumerate()
1696                {
1697                    uwriteln!(self.src, "case {}: {{", i);
1698                    self.src.push_str(&block);
1699                    assert!(block_results.len() == 1);
1700
1701                    if !self.gen.is_empty_type(iface, &case.ty) {
1702                        let mut dst = format!("{}.val", result);
1703                        dst.push_str(".");
1704                        dst.push_str(&case.name.to_snake_case());
1705                        self.store_op(&block_results[0], &dst);
1706                    }
1707                    self.src.push_str("break;\n}\n");
1708                }
1709                self.src.push_str("}\n");
1710                results.push(result);
1711            }
1712
1713            Instruction::UnionLower {
1714                union,
1715                results: result_types,
1716                ..
1717            } => {
1718                let blocks = self
1719                    .blocks
1720                    .drain(self.blocks.len() - union.cases.len()..)
1721                    .collect::<Vec<_>>();
1722                let payloads = self
1723                    .payloads
1724                    .drain(self.payloads.len() - union.cases.len()..)
1725                    .collect::<Vec<_>>();
1726
1727                let mut union_results = Vec::with_capacity(result_types.len());
1728                for ty in result_types.iter() {
1729                    let name = self.locals.tmp("unionres");
1730                    results.push(name.clone());
1731                    let ty = wasm_type(*ty);
1732                    uwriteln!(self.src, "{ty} {name};");
1733                    union_results.push(name);
1734                }
1735
1736                let op0 = &operands[0];
1737                uwriteln!(self.src, "switch (({op0}).tag) {{");
1738                for (i, ((case, (block, block_results)), payload)) in
1739                    union.cases.iter().zip(blocks).zip(payloads).enumerate()
1740                {
1741                    uwriteln!(self.src, "case {i}: {{");
1742                    if !self.gen.is_empty_type(iface, &case.ty) {
1743                        let ty = self.gen.type_string(iface, &case.ty);
1744                        uwriteln!(self.src, "const {ty} *{payload} = &({op0}).val.f{i};");
1745                    }
1746                    self.src.push_str(&block);
1747
1748                    for (name, result) in union_results.iter().zip(&block_results) {
1749                        uwriteln!(self.src, "{name} = {result};");
1750                    }
1751                    self.src.push_str("break;\n}\n");
1752                }
1753                self.src.push_str("}\n");
1754            }
1755
1756            Instruction::UnionLift { union, ty, .. } => {
1757                let blocks = self
1758                    .blocks
1759                    .drain(self.blocks.len() - union.cases.len()..)
1760                    .collect::<Vec<_>>();
1761
1762                let ty = self.gen.type_string(iface, &Type::Id(*ty));
1763                let result = self.locals.tmp("unionres");
1764                uwriteln!(self.src, "{} {};", ty, result);
1765                uwriteln!(self.src, "{}.tag = {};", result, operands[0]);
1766                uwriteln!(self.src, "switch ((int32_t) {}.tag) {{", result);
1767                for (i, (_case, (block, block_results))) in
1768                    union.cases.iter().zip(blocks).enumerate()
1769                {
1770                    uwriteln!(self.src, "case {i}: {{");
1771                    self.src.push_str(&block);
1772
1773                    assert!(block_results.len() == 1);
1774                    let dst = format!("{result}.val.f{i}");
1775                    self.store_op(&block_results[0], &dst);
1776                    self.src.push_str("break;\n}\n");
1777                }
1778                self.src.push_str("}\n");
1779                results.push(result);
1780            }
1781
1782            Instruction::OptionLower {
1783                results: result_types,
1784                payload,
1785                ..
1786            } => {
1787                let (mut some, some_results) = self.blocks.pop().unwrap();
1788                let (mut none, none_results) = self.blocks.pop().unwrap();
1789                let some_payload = self.payloads.pop().unwrap();
1790                let _none_payload = self.payloads.pop().unwrap();
1791
1792                for (i, ty) in result_types.iter().enumerate() {
1793                    let name = self.locals.tmp("option");
1794                    results.push(name.clone());
1795                    self.src.push_str(wasm_type(*ty));
1796                    self.src.push_str(" ");
1797                    self.src.push_str(&name);
1798                    self.src.push_str(";\n");
1799                    let some_result = &some_results[i];
1800                    uwriteln!(some, "{name} = {some_result};");
1801                    let none_result = &none_results[i];
1802                    uwriteln!(none, "{name} = {none_result};");
1803                }
1804
1805                let op0 = &operands[0];
1806                let ty = self.gen.type_string(iface, payload);
1807                let bind_some = if self.gen.is_empty_type(iface, payload) {
1808                    String::new()
1809                } else {
1810                    format!("const {ty} *{some_payload} = &({op0}).val;")
1811                };
1812                uwrite!(
1813                    self.src,
1814                    "
1815                    if (({op0}).is_some) {{
1816                        {bind_some}
1817                        {some}
1818                    }} else {{
1819                        {none}
1820                    }}
1821                    "
1822                );
1823            }
1824
1825            Instruction::OptionLift { payload, ty, .. } => {
1826                let (some, some_results) = self.blocks.pop().unwrap();
1827                let (none, none_results) = self.blocks.pop().unwrap();
1828                assert!(none_results.len() == 1);
1829                assert!(some_results.len() == 1);
1830                let some_result = &some_results[0];
1831                assert_eq!(none_results[0], "INVALID");
1832
1833                let ty = self.gen.type_string(iface, &Type::Id(*ty));
1834                let result = self.locals.tmp("option");
1835                uwriteln!(self.src, "{ty} {result};");
1836                let op0 = &operands[0];
1837                let set_some = if self.gen.is_empty_type(iface, payload) {
1838                    String::new()
1839                } else {
1840                    format!("{result}.val = {some_result};")
1841                };
1842                uwrite!(
1843                    self.src,
1844                    "switch ({op0}) {{
1845                        case 0: {{
1846                            {result}.is_some = false;
1847                            {none}
1848                            break;
1849                        }}
1850                        case 1: {{
1851                            {result}.is_some = true;
1852                            {some}
1853                            {set_some}
1854                            break;
1855                        }}
1856                    }}"
1857                );
1858                results.push(result);
1859            }
1860
1861            Instruction::ExpectedLower {
1862                results: result_types,
1863                expected,
1864                ..
1865            } => {
1866                let (mut err, err_results) = self.blocks.pop().unwrap();
1867                let (mut ok, ok_results) = self.blocks.pop().unwrap();
1868                let err_payload = self.payloads.pop().unwrap();
1869                let ok_payload = self.payloads.pop().unwrap();
1870
1871                for (i, ty) in result_types.iter().enumerate() {
1872                    let name = self.locals.tmp("expected");
1873                    results.push(name.clone());
1874                    self.src.push_str(wasm_type(*ty));
1875                    self.src.push_str(" ");
1876                    self.src.push_str(&name);
1877                    self.src.push_str(";\n");
1878                    let ok_result = &ok_results[i];
1879                    uwriteln!(ok, "{name} = {ok_result};");
1880                    let err_result = &err_results[i];
1881                    uwriteln!(err, "{name} = {err_result};");
1882                }
1883
1884                let op0 = &operands[0];
1885                let ok_ty = self.gen.type_string(iface, &expected.ok);
1886                let err_ty = self.gen.type_string(iface, &expected.err);
1887                let bind_ok = if self.gen.is_empty_type(iface, &expected.ok) {
1888                    String::new()
1889                } else {
1890                    format!("const {ok_ty} *{ok_payload} = &({op0}).val.ok;")
1891                };
1892                let bind_err = if self.gen.is_empty_type(iface, &expected.err) {
1893                    String::new()
1894                } else {
1895                    format!("const {err_ty} *{err_payload} = &({op0}).val.err;")
1896                };
1897                uwrite!(
1898                    self.src,
1899                    "
1900                    if (({op0}).is_err) {{
1901                        {bind_err}
1902                        {err}
1903                    }} else {{
1904                        {bind_ok}
1905                        {ok}
1906                    }}
1907                    "
1908                );
1909            }
1910
1911            Instruction::ExpectedLift { expected, ty, .. } => {
1912                let (err, err_results) = self.blocks.pop().unwrap();
1913                assert!(err_results.len() == 1);
1914                let err_result = &err_results[0];
1915                let (ok, ok_results) = self.blocks.pop().unwrap();
1916                assert!(ok_results.len() == 1);
1917                let ok_result = &ok_results[0];
1918
1919                let result = self.locals.tmp("expected");
1920                let set_ok = if self.gen.is_empty_type(iface, &expected.ok) {
1921                    String::new()
1922                } else {
1923                    format!("{result}.val.ok = {ok_result};")
1924                };
1925                let set_err = if self.gen.is_empty_type(iface, &expected.err) {
1926                    String::new()
1927                } else {
1928                    format!("{result}.val.err = {err_result};")
1929                };
1930
1931                let ty = self.gen.type_string(iface, &Type::Id(*ty));
1932                uwriteln!(self.src, "{ty} {result};");
1933                let op0 = &operands[0];
1934                uwrite!(
1935                    self.src,
1936                    "switch ({op0}) {{
1937                        case 0: {{
1938                            {result}.is_err = false;
1939                            {ok}
1940                            {set_ok}
1941                            break;
1942                        }}
1943                        case 1: {{
1944                            {result}.is_err = true;
1945                            {err}
1946                            {set_err}
1947                            break;
1948                        }}
1949                    }}"
1950                );
1951                results.push(result);
1952            }
1953
1954            Instruction::EnumLower { .. } => results.push(format!("(int32_t) {}", operands[0])),
1955            Instruction::EnumLift { .. } => results.push(operands.pop().unwrap()),
1956
1957            Instruction::ListCanonLower { .. } | Instruction::StringLower { .. } => {
1958                results.push(format!("(int32_t) ({}).ptr", operands[0]));
1959                results.push(format!("(int32_t) ({}).len", operands[0]));
1960            }
1961            Instruction::ListCanonLift { element, ty, .. } => {
1962                let list_name = self.gen.type_string(iface, &Type::Id(*ty));
1963                let elem_name = self.gen.type_string(iface, element);
1964                results.push(format!(
1965                    "({}) {{ ({}*)({}), (size_t)({}) }}",
1966                    list_name, elem_name, operands[0], operands[1]
1967                ));
1968            }
1969            Instruction::StringLift { .. } => {
1970                let list_name = self.gen.type_string(iface, &Type::String);
1971                results.push(format!(
1972                    "({}) {{ (char*)({}), (size_t)({}) }}",
1973                    list_name, operands[0], operands[1]
1974                ));
1975            }
1976
1977            Instruction::ListLower { .. } => {
1978                let _body = self.blocks.pop().unwrap();
1979                results.push(format!("(int32_t) ({}).ptr", operands[0]));
1980                results.push(format!("(int32_t) ({}).len", operands[0]));
1981            }
1982
1983            Instruction::ListLift { element, ty, .. } => {
1984                let _body = self.blocks.pop().unwrap();
1985                let list_name = self.gen.type_string(iface, &Type::Id(*ty));
1986                let elem_name = self.gen.type_string(iface, element);
1987                results.push(format!(
1988                    "({}) {{ ({}*)({}), (size_t)({}) }}",
1989                    list_name, elem_name, operands[0], operands[1]
1990                ));
1991            }
1992            Instruction::IterElem { .. } => results.push("e".to_string()),
1993            Instruction::IterBasePointer => results.push("base".to_string()),
1994
1995            Instruction::CallWasm { sig, .. } => {
1996                match sig.results.len() {
1997                    0 => {}
1998                    1 => {
1999                        self.src.push_str(wasm_type(sig.results[0]));
2000                        let ret = self.locals.tmp("ret");
2001                        self.wasm_return = Some(ret.clone());
2002                        uwrite!(self.src, " {} = ", ret);
2003                        results.push(ret);
2004                    }
2005                    _ => unimplemented!(),
2006                }
2007                self.src.push_str(self.func_to_call);
2008                self.src.push_str("(");
2009                for (i, op) in operands.iter().enumerate() {
2010                    if i > 0 {
2011                        self.src.push_str(", ");
2012                    }
2013                    self.src.push_str(op);
2014                }
2015                self.src.push_str(");\n");
2016            }
2017
2018            Instruction::CallInterface { module: _, func } => {
2019                let mut args = String::new();
2020                for (i, (op, (byref, _))) in operands.iter().zip(&self.sig.params).enumerate() {
2021                    if i > 0 {
2022                        args.push_str(", ");
2023                    }
2024                    if *byref {
2025                        let name = self.locals.tmp("arg");
2026                        let ty = self.gen.type_string(iface, &func.params[i].1);
2027                        uwriteln!(self.src, "{} {} = {};", ty, name, op);
2028                        args.push_str("&");
2029                        args.push_str(&name);
2030                    } else {
2031                        args.push_str(op);
2032                    }
2033                }
2034                match &self.sig.ret.scalar {
2035                    None => {
2036                        let mut retptrs = Vec::new();
2037                        for ty in self.sig.ret.retptrs.iter() {
2038                            let name = self.locals.tmp("ret");
2039                            let ty = self.gen.type_string(iface, ty);
2040                            uwriteln!(self.src, "{} {};", ty, name);
2041                            if args.len() > 0 {
2042                                args.push_str(", ");
2043                            }
2044                            args.push_str("&");
2045                            args.push_str(&name);
2046                            retptrs.push(name);
2047                        }
2048                        uwriteln!(self.src, "{}({});", self.sig.name, args);
2049                        if self.sig.ret.splat_tuple {
2050                            let ty = self.gen.type_string(iface, &func.result);
2051                            results.push(format!("({}){{ {} }}", ty, retptrs.join(", ")));
2052                        } else if self.sig.retptrs.len() > 0 {
2053                            results.extend(retptrs);
2054                        }
2055                    }
2056                    Some(Scalar::Void) => {
2057                        uwriteln!(self.src, "{}({});", self.sig.name, args);
2058                        results.push("INVALID".to_string());
2059                    }
2060                    Some(Scalar::Type(_)) => {
2061                        let ret = self.locals.tmp("ret");
2062                        let ty = self.gen.type_string(iface, &func.result);
2063                        uwriteln!(self.src, "{} {} = {}({});", ty, ret, self.sig.name, args);
2064                        results.push(ret);
2065                    }
2066                    Some(Scalar::OptionBool(ty)) => {
2067                        let ret = self.locals.tmp("ret");
2068                        let val = self.locals.tmp("val");
2069                        if args.len() > 0 {
2070                            args.push_str(", ");
2071                        }
2072                        args.push_str("&");
2073                        args.push_str(&val);
2074                        let payload_ty = self.gen.type_string(iface, ty);
2075                        uwriteln!(self.src, "{} {};", payload_ty, val);
2076                        uwriteln!(self.src, "bool {} = {}({});", ret, self.sig.name, args);
2077                        let option_ty = self.gen.type_string(iface, &func.result);
2078                        let option_ret = self.locals.tmp("ret");
2079                        uwrite!(
2080                            self.src,
2081                            "
2082                                {ty} {ret};
2083                                {ret}.is_some = {tag};
2084                                {ret}.val = {val};
2085                            ",
2086                            ty = option_ty,
2087                            ret = option_ret,
2088                            tag = ret,
2089                            val = val,
2090                        );
2091                        results.push(option_ret);
2092                    }
2093                    Some(Scalar::ExpectedEnum { err, max_err }) => {
2094                        let ret = self.locals.tmp("ret");
2095                        let mut ok_names = Vec::new();
2096                        for ty in self.sig.ret.retptrs.iter() {
2097                            let val = self.locals.tmp("ok");
2098                            if args.len() > 0 {
2099                                args.push_str(", ");
2100                            }
2101                            args.push_str("&");
2102                            args.push_str(&val);
2103                            let ty = self.gen.type_string(iface, ty);
2104                            uwriteln!(self.src, "{} {};", ty, val);
2105                            ok_names.push(val);
2106                        }
2107                        let err_ty = self.gen.type_string(iface, &Type::Id(*err));
2108                        uwriteln!(
2109                            self.src,
2110                            "{} {} = {}({});",
2111                            err_ty,
2112                            ret,
2113                            self.sig.name,
2114                            args,
2115                        );
2116                        let expected_ty = self.gen.type_string(iface, &func.result);
2117                        let expected_ret = self.locals.tmp("ret");
2118                        uwrite!(
2119                            self.src,
2120                            "
2121                                {ty} {ret};
2122                                if ({tag} <= {max}) {{
2123                                    {ret}.is_err = true;
2124                                    {ret}.val.err = {tag};
2125                                }} else {{
2126                                    {ret}.is_err = false;
2127                                    {set_ok}
2128                                }}
2129                            ",
2130                            ty = expected_ty,
2131                            ret = expected_ret,
2132                            tag = ret,
2133                            max = max_err,
2134                            set_ok = if self.sig.ret.retptrs.len() == 0 {
2135                                String::new()
2136                            } else if self.sig.ret.splat_tuple {
2137                                let mut s = String::new();
2138                                for (i, name) in ok_names.iter().enumerate() {
2139                                    uwriteln!(s, "{}.val.ok.f{} = {};", expected_ret, i, name,);
2140                                }
2141                                s
2142                            } else {
2143                                let name = ok_names.pop().unwrap();
2144                                format!("{}.val.ok = {};", expected_ret, name)
2145                            },
2146                        );
2147                        results.push(expected_ret);
2148                    }
2149                }
2150            }
2151            Instruction::Return { .. } if self.gen.in_import => match self.sig.ret.scalar {
2152                None => self.store_in_retptrs(operands),
2153                Some(Scalar::Void) => {
2154                    assert_eq!(operands, &["INVALID"]);
2155                }
2156                Some(Scalar::Type(_)) => {
2157                    assert_eq!(operands.len(), 1);
2158                    self.src.push_str("return ");
2159                    self.src.push_str(&operands[0]);
2160                    self.src.push_str(";\n");
2161                }
2162                Some(Scalar::OptionBool(_)) => {
2163                    assert_eq!(operands.len(), 1);
2164                    let variant = &operands[0];
2165                    self.store_in_retptrs(&[format!("{}.val", variant)]);
2166                    self.src.push_str("return ");
2167                    self.src.push_str(&variant);
2168                    self.src.push_str(".is_some;\n");
2169                }
2170                Some(Scalar::ExpectedEnum { .. }) => {
2171                    assert_eq!(operands.len(), 1);
2172                    let variant = &operands[0];
2173                    if self.sig.retptrs.len() > 0 {
2174                        self.store_in_retptrs(&[format!("{}.val.ok", variant)]);
2175                    }
2176                    uwriteln!(self.src, "return {}.is_err ? {0}.val.err : -1;", variant);
2177                }
2178            },
2179            Instruction::Return { amt, .. } => {
2180                assert!(*amt <= 1);
2181                if *amt == 1 {
2182                    uwriteln!(self.src, "return {};", operands[0]);
2183                }
2184            }
2185
2186            Instruction::I32Load { offset } => self.load("int32_t", *offset, operands, results),
2187            Instruction::I64Load { offset } => self.load("int64_t", *offset, operands, results),
2188            Instruction::F32Load { offset } => self.load("float", *offset, operands, results),
2189            Instruction::F64Load { offset } => self.load("double", *offset, operands, results),
2190            Instruction::I32Store { offset } => self.store("int32_t", *offset, operands),
2191            Instruction::I64Store { offset } => self.store("int64_t", *offset, operands),
2192            Instruction::F32Store { offset } => self.store("float", *offset, operands),
2193            Instruction::F64Store { offset } => self.store("double", *offset, operands),
2194            Instruction::I32Store8 { offset } => self.store("int8_t", *offset, operands),
2195            Instruction::I32Store16 { offset } => self.store("int16_t", *offset, operands),
2196
2197            Instruction::I32Load8U { offset } => {
2198                self.load_ext("uint8_t", *offset, operands, results)
2199            }
2200            Instruction::I32Load8S { offset } => {
2201                self.load_ext("int8_t", *offset, operands, results)
2202            }
2203            Instruction::I32Load16U { offset } => {
2204                self.load_ext("uint16_t", *offset, operands, results)
2205            }
2206            Instruction::I32Load16S { offset } => {
2207                self.load_ext("int16_t", *offset, operands, results)
2208            }
2209
2210            Instruction::Free { .. } => {
2211                uwriteln!(self.src, "free((void*) ({}));", operands[0]);
2212            }
2213
2214            i => unimplemented!("{:?}", i),
2215        }
2216    }
2217}
2218
2219#[derive(Default)]
2220struct Source {
2221    h: wai_bindgen_gen_core::Source,
2222    c: wai_bindgen_gen_core::Source,
2223}
2224
2225impl Source {
2226    fn c(&mut self, s: &str) {
2227        self.c.push_str(s);
2228    }
2229    fn h(&mut self, s: &str) {
2230        self.h.push_str(s);
2231    }
2232}
2233
2234fn wasm_type(ty: WasmType) -> &'static str {
2235    match ty {
2236        WasmType::I32 => "int32_t",
2237        WasmType::I64 => "int64_t",
2238        WasmType::F32 => "float",
2239        WasmType::F64 => "double",
2240    }
2241}
2242
2243fn int_repr(ty: Int) -> &'static str {
2244    match ty {
2245        Int::U8 => "uint8_t",
2246        Int::U16 => "uint16_t",
2247        Int::U32 => "uint32_t",
2248        Int::U64 => "uint64_t",
2249    }
2250}
2251
2252fn flags_repr(f: &Flags) -> Int {
2253    match f.repr() {
2254        FlagsRepr::U8 => Int::U8,
2255        FlagsRepr::U16 => Int::U16,
2256        FlagsRepr::U32(1) => Int::U32,
2257        FlagsRepr::U32(2) => Int::U64,
2258        repr => panic!("unimplemented flags {:?}", repr),
2259    }
2260}