linera_wit_bindgen_gen_host_wasmer_rust/
lib.rs

1use heck::*;
2use std::collections::{BTreeMap, BTreeSet, HashMap};
3use std::io::{Read, Write};
4use std::mem;
5use std::process::{Command, Stdio};
6use wit_bindgen_core::wit_parser::abi::{AbiVariant, Bindgen, Instruction, LiftLower, WasmType};
7use wit_bindgen_core::{wit_parser::*, Direction, Files, Generator, Source, TypeInfo, Types};
8use wit_bindgen_gen_rust_lib::{
9    to_rust_ident, wasm_type, FnSig, RustFlagsRepr, RustFunctionGenerator, RustGenerator, TypeMode,
10};
11
12#[derive(Default)]
13pub struct Wasmer {
14    src: Source,
15    opts: Opts,
16    needs_memory: bool,
17    needs_functions: BTreeMap<String, NeededFunction>,
18    needs_char_from_i32: bool,
19    needs_invalid_variant: bool,
20    needs_validate_flags: bool,
21    needs_raw_mem: bool,
22    needs_bad_int: bool,
23    needs_copy_slice: bool,
24    needs_buffer_glue: bool,
25    needs_le: bool,
26    needs_custom_error_to_trap: bool,
27    needs_custom_error_to_types: BTreeSet<String>,
28    needs_lazy_initialized: bool,
29    all_needed_handles: BTreeSet<String>,
30    exported_resources: BTreeSet<ResourceId>,
31    types: Types,
32    guest_imports: HashMap<String, Vec<Import>>,
33    guest_exports: HashMap<String, Exports>,
34    in_import: bool,
35    in_trait: bool,
36    trait_name: String,
37    sizes: SizeAlign,
38}
39
40enum NeededFunction {
41    Realloc,
42    Free,
43}
44
45struct Import {
46    name: String,
47    trait_signature: String,
48    closure: String,
49}
50
51#[derive(Default)]
52struct Exports {
53    fields: BTreeMap<String, (String, String)>,
54    funcs: Vec<String>,
55}
56
57#[derive(Default, Debug, Clone)]
58#[cfg_attr(feature = "structopt", derive(structopt::StructOpt))]
59pub struct Opts {
60    /// Whether or not `rustfmt` is executed to format generated code.
61    #[cfg_attr(feature = "structopt", structopt(long))]
62    pub rustfmt: bool,
63
64    /// Whether or not to emit `tracing` macro calls on function entry/exit.
65    #[cfg_attr(feature = "structopt", structopt(long))]
66    pub tracing: bool,
67
68    /// A flag to indicate that all trait methods in imports should return a
69    /// custom trait-defined error. Applicable for import bindings.
70    #[cfg_attr(feature = "structopt", structopt(long))]
71    pub custom_error: bool,
72}
73
74impl Opts {
75    pub fn build(self) -> Wasmer {
76        let mut r = Wasmer::new();
77        r.opts = self;
78        r
79    }
80}
81
82enum FunctionRet {
83    /// The function return is normal and needs to extra handling.
84    Normal,
85    /// The function return was wrapped in a `Result` in Rust. The `Ok` variant
86    /// is the actual value that will be lowered, and the `Err`, if present,
87    /// means that a trap has occurred.
88    CustomToTrap,
89    /// The function returns a `Result` in both wasm and in Rust, but the
90    /// Rust error type is a custom error and must be converted to `err`. The
91    /// `ok` variant payload is provided here too.
92    CustomToError { ok: Type, err: String },
93}
94
95impl Wasmer {
96    pub fn new() -> Wasmer {
97        Wasmer::default()
98    }
99
100    fn abi_variant(dir: Direction) -> AbiVariant {
101        // This generator uses a reversed mapping! In the Wasmer host-side
102        // bindings, we don't use any extra adapter layer between guest wasm
103        // modules and the host. When the guest imports functions using the
104        // `GuestImport` ABI, the host directly implements the `GuestImport`
105        // ABI, even though the host is *exporting* functions. Similarly, when
106        // the guest exports functions using the `GuestExport` ABI, the host
107        // directly imports them with the `GuestExport` ABI, even though the
108        // host is *importing* functions.
109        match dir {
110            Direction::Import => AbiVariant::GuestExport,
111            Direction::Export => AbiVariant::GuestImport,
112        }
113    }
114
115    fn print_intrinsics(&mut self) {
116        if self.needs_lazy_initialized || !self.exported_resources.is_empty() {
117            self.push_str("use wit_bindgen_host_wasmer_rust::once_cell::unsync::OnceCell;\n");
118        }
119
120        self.push_str("#[allow(unused_imports)]\n");
121        self.push_str("use wasmer::AsStoreMut as _;\n");
122        self.push_str("#[allow(unused_imports)]\n");
123        self.push_str("use wasmer::AsStoreRef as _;\n");
124        if self.needs_raw_mem {
125            self.push_str("use wit_bindgen_host_wasmer_rust::rt::RawMem;\n");
126        }
127        if self.needs_char_from_i32 {
128            self.push_str("use wit_bindgen_host_wasmer_rust::rt::char_from_i32;\n");
129        }
130        if self.needs_invalid_variant {
131            self.push_str("use wit_bindgen_host_wasmer_rust::rt::invalid_variant;\n");
132        }
133        if self.needs_bad_int {
134            self.push_str("use core::convert::TryFrom;\n");
135            self.push_str("use wit_bindgen_host_wasmer_rust::rt::bad_int;\n");
136        }
137        if self.needs_validate_flags {
138            self.push_str("use wit_bindgen_host_wasmer_rust::rt::validate_flags;\n");
139        }
140        if self.needs_le {
141            self.push_str("use wit_bindgen_host_wasmer_rust::Le;\n");
142        }
143        if self.needs_copy_slice {
144            self.push_str("use wit_bindgen_host_wasmer_rust::rt::copy_slice;\n");
145        }
146    }
147
148    /// Classifies the return value of a function to see if it needs handling
149    /// with respect to the `custom_error` configuration option.
150    fn classify_fn_ret(&mut self, iface: &Interface, f: &Function) -> FunctionRet {
151        if !self.opts.custom_error {
152            return FunctionRet::Normal;
153        }
154
155        if let Type::Id(id) = &f.result {
156            if let TypeDefKind::Result(r) = &iface.types[*id].kind {
157                if let Type::Id(err) = r.err {
158                    if let Some(name) = &iface.types[err].name {
159                        self.needs_custom_error_to_types.insert(name.clone());
160                        return FunctionRet::CustomToError {
161                            ok: r.ok,
162                            err: name.to_string(),
163                        };
164                    }
165                }
166            }
167        }
168
169        self.needs_custom_error_to_trap = true;
170        FunctionRet::CustomToTrap
171    }
172}
173
174impl RustGenerator for Wasmer {
175    fn default_param_mode(&self) -> TypeMode {
176        if self.in_import {
177            // The default here is that only leaf values can be borrowed because
178            // otherwise lists and such need to be copied into our own memory.
179            TypeMode::LeafBorrowed("'a")
180        } else {
181            // When we're calling wasm exports, however, there's no need to take
182            // any ownership of anything from the host so everything is borrowed
183            // in the parameter position.
184            TypeMode::AllBorrowed("'a")
185        }
186    }
187
188    fn handle_projection(&self) -> Option<(&'static str, String)> {
189        if self.in_import {
190            if self.in_trait {
191                Some(("Self", self.trait_name.clone()))
192            } else {
193                Some(("T", self.trait_name.clone()))
194            }
195        } else {
196            None
197        }
198    }
199
200    fn handle_wrapper(&self) -> Option<String> {
201        None
202    }
203
204    fn push_str(&mut self, s: &str) {
205        self.src.push_str(s);
206    }
207
208    fn info(&self, ty: TypeId) -> TypeInfo {
209        self.types.get(ty)
210    }
211
212    fn types_mut(&mut self) -> &mut Types {
213        &mut self.types
214    }
215
216    fn print_borrowed_slice(
217        &mut self,
218        iface: &Interface,
219        mutbl: bool,
220        ty: &Type,
221        lifetime: &'static str,
222    ) {
223        if self.sizes.align(ty) > 1 && self.in_import {
224            // If we're generating bindings for an import we ideally want to
225            // hand out raw pointers into memory. We can't guarantee anything
226            // about alignment in memory, though, so if the alignment
227            // requirement is bigger than one then we have to use slices where
228            // the type has a `Le<...>` wrapper.
229            //
230            // For exports we're generating functions that take values from
231            // Rust, so we can assume alignment and use raw slices. For types
232            // with an align of 1, then raw pointers are fine since Rust will
233            // have the same alignment requirement.
234            self.needs_le = true;
235            self.push_str("&");
236            if lifetime != "'_" {
237                self.push_str(lifetime);
238                self.push_str(" ");
239            }
240            if mutbl {
241                self.push_str(" mut ");
242            }
243            self.push_str("[Le<");
244            self.print_ty(iface, ty, TypeMode::AllBorrowed(lifetime));
245            self.push_str(">]");
246        } else {
247            self.print_rust_slice(iface, mutbl, ty, lifetime);
248        }
249    }
250
251    fn print_borrowed_str(&mut self, lifetime: &'static str) {
252        self.push_str("&");
253        if lifetime != "'_" {
254            self.push_str(lifetime);
255            self.push_str(" ");
256        }
257        self.push_str(" str");
258    }
259}
260
261impl Generator for Wasmer {
262    fn preprocess_one(&mut self, iface: &Interface, dir: Direction) {
263        let variant = Self::abi_variant(dir);
264        self.types.analyze(iface);
265        self.in_import = variant == AbiVariant::GuestImport;
266        self.trait_name = iface.name.to_camel_case();
267        self.src.push_str(&format!(
268            "#[allow(clippy::all)]\npub mod {} {{\n",
269            iface.name.to_snake_case()
270        ));
271        self.src.push_str(
272            "#[allow(unused_imports)]\nuse wit_bindgen_host_wasmer_rust::{anyhow, wasmer};\n",
273        );
274        self.sizes.fill(iface);
275    }
276
277    fn type_record(
278        &mut self,
279        iface: &Interface,
280        id: TypeId,
281        name: &str,
282        record: &Record,
283        docs: &Docs,
284    ) {
285        self.print_typedef_record(iface, id, record, docs);
286
287        // If this record might be used as a slice type in various places then
288        // we synthesize an `Endian` implementation for it so `&[Le<ThisType>]`
289        // is usable.
290        if self.modes_of(iface, id).len() > 0
291            && record.fields.iter().all(|f| iface.all_bits_valid(&f.ty))
292        {
293            self.src
294                .push_str("impl wit_bindgen_host_wasmer_rust::Endian for ");
295            self.src.push_str(&name.to_camel_case());
296            self.src.push_str(" {\n");
297
298            self.src.push_str("fn into_le(self) -> Self {\n");
299            self.src.push_str("Self {\n");
300            for field in record.fields.iter() {
301                self.src.push_str(&field.name.to_snake_case());
302                self.src.push_str(": self.");
303                self.src.push_str(&field.name.to_snake_case());
304                self.src.push_str(".into_le(),\n");
305            }
306            self.src.push_str("}\n");
307            self.src.push_str("}\n");
308
309            self.src.push_str("fn from_le(self) -> Self {\n");
310            self.src.push_str("Self {\n");
311            for field in record.fields.iter() {
312                self.src.push_str(&field.name.to_snake_case());
313                self.src.push_str(": self.");
314                self.src.push_str(&field.name.to_snake_case());
315                self.src.push_str(".from_le(),\n");
316            }
317            self.src.push_str("}\n");
318            self.src.push_str("}\n");
319
320            self.src.push_str("}\n");
321
322            // Also add an `AllBytesValid` valid impl since this structure's
323            // byte representations are valid (guarded by the `all_bits_valid`
324            // predicate).
325            self.src
326                .push_str("unsafe impl wit_bindgen_host_wasmer_rust::AllBytesValid for ");
327            self.src.push_str(&name.to_camel_case());
328            self.src.push_str(" {}\n");
329        }
330    }
331
332    fn type_tuple(
333        &mut self,
334        iface: &Interface,
335        id: TypeId,
336        _name: &str,
337        tuple: &Tuple,
338        docs: &Docs,
339    ) {
340        self.print_typedef_tuple(iface, id, tuple, docs);
341    }
342
343    fn type_flags(
344        &mut self,
345        _iface: &Interface,
346        _id: TypeId,
347        name: &str,
348        flags: &Flags,
349        docs: &Docs,
350    ) {
351        self.src
352            .push_str("wit_bindgen_host_wasmer_rust::bitflags::bitflags! {\n");
353        self.rustdoc(docs);
354        let repr = RustFlagsRepr::new(flags);
355        self.src
356            .push_str(&format!("pub struct {}: {repr} {{", name.to_camel_case()));
357        for (i, flag) in flags.flags.iter().enumerate() {
358            self.rustdoc(&flag.docs);
359            self.src.push_str(&format!(
360                "const {} = 1 << {};\n",
361                flag.name.to_shouty_snake_case(),
362                i,
363            ));
364        }
365        self.src.push_str("}\n");
366        self.src.push_str("}\n\n");
367
368        self.src.push_str("impl core::fmt::Display for ");
369        self.src.push_str(&name.to_camel_case());
370        self.src.push_str(
371            "{\nfn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n",
372        );
373
374        self.src.push_str("f.write_str(\"");
375        self.src.push_str(&name.to_camel_case());
376        self.src.push_str("(\")?;\n");
377        self.src.push_str("core::fmt::Debug::fmt(self, f)?;\n");
378        self.src.push_str("f.write_str(\" (0x\")?;\n");
379        self.src
380            .push_str("core::fmt::LowerHex::fmt(&self.bits, f)?;\n");
381        self.src.push_str("f.write_str(\"))\")?;\n");
382        self.src.push_str("Ok(())");
383
384        self.src.push_str("}\n");
385        self.src.push_str("}\n\n");
386    }
387
388    fn type_variant(
389        &mut self,
390        iface: &Interface,
391        id: TypeId,
392        _name: &str,
393        variant: &Variant,
394        docs: &Docs,
395    ) {
396        self.print_typedef_variant(iface, id, variant, docs);
397    }
398
399    fn type_enum(&mut self, _iface: &Interface, id: TypeId, name: &str, enum_: &Enum, docs: &Docs) {
400        self.print_typedef_enum(id, name, enum_, docs);
401    }
402
403    fn type_union(
404        &mut self,
405        iface: &Interface,
406        id: TypeId,
407        _name: &str,
408        union: &Union,
409        docs: &Docs,
410    ) {
411        self.print_typedef_union(iface, id, union, docs);
412    }
413
414    fn type_option(
415        &mut self,
416        iface: &Interface,
417        id: TypeId,
418        _name: &str,
419        payload: &Type,
420        docs: &Docs,
421    ) {
422        self.print_typedef_option(iface, id, payload, docs);
423    }
424
425    fn type_result(
426        &mut self,
427        iface: &Interface,
428        id: TypeId,
429        _name: &str,
430        result: &Result_,
431        docs: &Docs,
432    ) {
433        self.print_typedef_result(iface, id, result, docs);
434    }
435
436    fn type_resource(&mut self, iface: &Interface, ty: ResourceId) {
437        let name = &iface.resources[ty].name;
438        self.all_needed_handles.insert(name.to_string());
439
440        // If we're binding imports then all handles are associated types so
441        // there's nothing that we need to do about that.
442        if self.in_import {
443            return;
444        }
445
446        self.exported_resources.insert(ty);
447
448        // ... otherwise for exports we generate a newtype wrapper around an
449        // `i32` to manage the resultt.
450        let tyname = name.to_camel_case();
451        self.rustdoc(&iface.resources[ty].docs);
452        self.src.push_str("#[derive(Debug)]\n");
453        self.src.push_str(&format!(
454            "pub struct {}(wit_bindgen_host_wasmer_rust::rt::ResourceIndex);\n",
455            tyname
456        ));
457    }
458
459    fn type_alias(&mut self, iface: &Interface, id: TypeId, _name: &str, ty: &Type, docs: &Docs) {
460        self.print_typedef_alias(iface, id, ty, docs);
461    }
462
463    fn type_list(&mut self, iface: &Interface, id: TypeId, _name: &str, ty: &Type, docs: &Docs) {
464        self.print_type_list(iface, id, ty, docs);
465    }
466
467    fn type_builtin(&mut self, iface: &Interface, _id: TypeId, name: &str, ty: &Type, docs: &Docs) {
468        self.rustdoc(docs);
469        self.src
470            .push_str(&format!("pub type {}", name.to_camel_case()));
471        self.src.push_str(" = ");
472        self.print_ty(iface, ty, TypeMode::Owned);
473        self.src.push_str(";\n");
474    }
475
476    // As with `abi_variant` above, we're generating host-side bindings here
477    // so a user "export" uses the "guest import" ABI variant on the inside of
478    // this `Generator` implementation.
479    fn export(&mut self, iface: &Interface, func: &Function) {
480        let prev = mem::take(&mut self.src);
481
482        // Generate the closure that's passed to a `Linker`, the final piece of
483        // codegen here.
484        let sig = iface.wasm_signature(AbiVariant::GuestImport, func);
485        let params = (0..sig.params.len())
486            .map(|i| format!("arg{}", i))
487            .collect::<Vec<_>>();
488        let mut f = FunctionBindgen::new(self, params);
489        iface.call(
490            AbiVariant::GuestImport,
491            LiftLower::LiftArgsLowerResults,
492            func,
493            &mut f,
494        );
495        let FunctionBindgen {
496            src,
497            cleanup,
498            needs_borrow_checker,
499            needs_memory,
500            needs_buffer_transaction,
501            needs_functions,
502            closures,
503            ..
504        } = f;
505        assert!(cleanup.is_none());
506        assert!(!needs_buffer_transaction);
507
508        // Generate the signature this function will have in the final trait
509        let self_arg = "&mut self".to_string();
510        self.in_trait = true;
511
512        let mut fnsig = FnSig::default();
513        fnsig.private = true;
514        fnsig.self_arg = Some(self_arg);
515        self.print_docs_and_params(iface, func, TypeMode::LeafBorrowed("'_"), &fnsig);
516        // The Rust return type may differ from the wasm return type based on
517        // the `custom_error` configuration of this code generator.
518        match self.classify_fn_ret(iface, func) {
519            FunctionRet::Normal => {
520                self.push_str(" -> ");
521                self.print_ty(iface, &func.result, TypeMode::Owned);
522            }
523            FunctionRet::CustomToTrap => {
524                self.push_str(" -> Result<");
525                self.print_ty(iface, &func.result, TypeMode::Owned);
526                self.push_str(", Self::Error>");
527            }
528            FunctionRet::CustomToError { ok, .. } => {
529                self.push_str(" -> Result<");
530                self.print_ty(iface, &ok, TypeMode::Owned);
531                self.push_str(", Self::Error>");
532            }
533        }
534        self.in_trait = false;
535        let trait_signature = mem::take(&mut self.src).into();
536
537        // Generate the closure that's passed to a `Linker`, the final piece of
538        // codegen here.
539        let result_ty = match &sig.results[..] {
540            &[] => format!("()"),
541            &[ty] => format!("{}", wasm_type(ty)),
542            tys => format!(
543                "({})",
544                tys.iter()
545                    .map(|&ty| wasm_type(ty))
546                    .collect::<Vec<_>>()
547                    .join(", ")
548            ),
549        };
550        self.src
551            .push_str("move |mut store: wasmer::FunctionEnvMut<EnvWrapper<T>>");
552        for (i, param) in sig.params.iter().enumerate() {
553            let arg = format!("arg{}", i);
554            self.src.push_str(",");
555            self.src.push_str(&arg);
556            self.src.push_str(":");
557            self.wasm_type(*param);
558        }
559        self.src.push_str(&format!(
560            "| -> Result<{}, wasmer::RuntimeError> {{\n",
561            result_ty
562        ));
563
564        if self.opts.tracing {
565            self.src.push_str(&format!(
566                "
567                    let span = wit_bindgen_host_wasmer_rust::tracing::span!(
568                        wit_bindgen_host_wasmer_rust::tracing::Level::TRACE,
569                        \"wit-bindgen abi\",
570                        module = \"{}\",
571                        function = \"{}\",
572                    );
573                    let _enter = span.enter();
574                ",
575                iface.name, func.name,
576            ));
577        }
578        self.src.push_str(&closures);
579
580        for name in needs_functions.keys() {
581            self.src.push_str(&format!(
582                "let func_{name} = store
583                    .data()
584                    .lazy
585                    .get()
586                    .unwrap()
587                    .func_{name}
588                    .clone();\n"
589            ));
590        }
591        self.needs_functions.extend(needs_functions);
592        self.needs_memory |= needs_memory || needs_borrow_checker;
593
594        if self.needs_memory {
595            self.src.push_str(
596                "let _memory: wasmer::Memory = store.data().lazy.get().unwrap().memory.clone();\n",
597            );
598        }
599
600        if needs_borrow_checker {
601            // TODO: This isn't actually sound and should be replaced with use
602            // of WasmPtr/WasmCell.
603            self.src.push_str(
604                "let _memory_view = _memory.view(&store);
605                let mut _bc = wit_bindgen_host_wasmer_rust::BorrowChecker::new(unsafe {
606                        _memory_view.data_unchecked_mut()
607                 });\n",
608            );
609        }
610
611        self.src.push_str("let data_mut = store.data_mut();\n");
612
613        if self.all_needed_handles.len() > 0 {
614            self.src
615                .push_str("let tables = data_mut.tables.borrow_mut();\n");
616        }
617
618        self.src.push_str(&String::from(src));
619
620        self.src.push_str("}");
621        let closure = mem::replace(&mut self.src, prev).into();
622
623        self.guest_imports
624            .entry(iface.name.to_string())
625            .or_insert(Vec::new())
626            .push(Import {
627                name: iface.mangle_funcname(func),
628                closure,
629                trait_signature,
630            });
631    }
632
633    // As with `abi_variant` above, we're generating host-side bindings here
634    // so a user "import" uses the "export" ABI variant on the inside of
635    // this `Generator` implementation.
636    fn import(&mut self, iface: &Interface, func: &Function) {
637        let prev = mem::take(&mut self.src);
638
639        let mut sig = FnSig::default();
640
641        // Adding the store to the self_arg is an ugly workaround, but the
642        // FnSig and Function types don't really leave a lot of room for
643        // implementing this in a better way.
644        sig.self_arg = Some("&self, store: &mut wasmer::Store".to_string());
645        self.print_docs_and_params(iface, func, TypeMode::AllBorrowed("'_"), &sig);
646        self.push_str("-> Result<");
647        self.print_ty(iface, &func.result, TypeMode::Owned);
648        self.push_str(", wasmer::RuntimeError> {\n");
649
650        let params = func
651            .params
652            .iter()
653            .map(|(name, _)| to_rust_ident(name).to_string())
654            .collect();
655        let mut f = FunctionBindgen::new(self, params);
656        iface.call(
657            AbiVariant::GuestExport,
658            LiftLower::LowerArgsLiftResults,
659            func,
660            &mut f,
661        );
662        let FunctionBindgen {
663            needs_memory,
664            src,
665            needs_borrow_checker,
666            needs_buffer_transaction,
667            closures,
668            needs_functions,
669            ..
670        } = f;
671
672        let exports = self
673            .guest_exports
674            .entry(iface.name.to_string())
675            .or_insert_with(Exports::default);
676
677        for (name, func) in needs_functions {
678            self.src
679                .push_str(&format!("let func_{name} = &self.func_{name};\n"));
680            let get = format!("_instance.exports.get_typed_function(&store, \"{name}\")?",);
681            exports
682                .fields
683                .insert(format!("func_{name}"), (func.ty(), get));
684        }
685
686        self.src.push_str(&closures);
687
688        assert!(!needs_borrow_checker);
689        if needs_memory {
690            self.src.push_str("let _memory = &self.memory;\n");
691            exports.fields.insert(
692                "memory".to_string(),
693                (
694                    "wasmer::Memory".to_string(),
695                    "_instance.exports.get_memory(\"memory\")?.clone()".to_string(),
696                ),
697            );
698        }
699
700        if needs_buffer_transaction {
701            self.needs_buffer_glue = true;
702            self.src
703                .push_str("let mut buffer_transaction = self.buffer_glue.transaction();\n");
704        }
705
706        self.src.push_str(&String::from(src));
707        self.src.push_str("}\n");
708        let func_body = mem::replace(&mut self.src, prev);
709        exports.funcs.push(func_body.into());
710
711        // Create the code snippet which will define the type of this field in
712        // the struct that we're exporting and additionally extracts the
713        // function from an instantiated instance.
714        let sig = iface.wasm_signature(AbiVariant::GuestExport, func);
715        let mut cvt = String::new();
716        if sig.params.len() == 1 {
717            cvt.push_str(wasm_type(sig.params[0]));
718        } else {
719            cvt.push_str("(");
720            for param in sig.params.iter() {
721                cvt.push_str(wasm_type(*param));
722                cvt.push_str(",");
723            }
724            cvt.push_str(")");
725        }
726        cvt.push_str(", ");
727        if sig.results.len() == 1 {
728            cvt.push_str(wasm_type(sig.results[0]));
729        } else {
730            cvt.push_str("(");
731            for result in sig.results.iter() {
732                cvt.push_str(wasm_type(*result));
733                cvt.push_str(",");
734            }
735            cvt.push_str(")");
736        }
737        exports.fields.insert(
738            format!("func_{}", to_rust_ident(&func.name)),
739            (
740                format!("wasmer::TypedFunction<{cvt}>"),
741                format!(
742                    "_instance.exports.get_typed_function(&store, \"{}\")?",
743                    iface.mangle_funcname(func),
744                ),
745            ),
746        );
747    }
748
749    fn finish_one(&mut self, iface: &Interface, files: &mut Files) {
750        for (module, funcs) in sorted_iter(&self.guest_imports) {
751            let module_camel = module.to_camel_case();
752            self.src.push_str("pub trait ");
753            self.src.push_str(&module_camel);
754            self.src.push_str(": Sized + Send + Sync + 'static");
755            self.src.push_str("{\n");
756            if self.all_needed_handles.len() > 0 {
757                for handle in self.all_needed_handles.iter() {
758                    self.src.push_str("type ");
759                    self.src.push_str(&handle.to_camel_case());
760                    self.src.push_str(": std::fmt::Debug");
761                    self.src.push_str(";\n");
762                }
763            }
764            if self.opts.custom_error {
765                self.src.push_str("type Error;\n");
766                if self.needs_custom_error_to_trap {
767                    self.src.push_str(
768                        "fn error_to_trap(&mut self, err: Self::Error) -> wasmer::RuntimeError;\n",
769                    );
770                }
771                for ty in self.needs_custom_error_to_types.iter() {
772                    self.src.push_str(&format!(
773                        "fn error_to_{}(&mut self, err: Self::Error) -> Result<{}, wasmer::RuntimeError>;\n",
774                        ty.to_snake_case(),
775                        ty.to_camel_case(),
776                    ));
777                }
778            }
779            for f in funcs {
780                self.src.push_str(&f.trait_signature);
781                self.src.push_str(";\n\n");
782            }
783            for handle in self.all_needed_handles.iter() {
784                self.src.push_str(&format!(
785                    "fn drop_{}(&mut self, state: Self::{}) {{
786                        drop(state);
787                    }}\n",
788                    handle.to_snake_case(),
789                    handle.to_camel_case(),
790                ));
791            }
792            self.src.push_str("}\n");
793
794            if self.all_needed_handles.len() > 0 {
795                self.src.push_str("\npub struct ");
796                self.src.push_str(&module_camel);
797                self.src.push_str("Tables<T: ");
798                self.src.push_str(&module_camel);
799                self.src.push_str("> {\n");
800                for handle in self.all_needed_handles.iter() {
801                    self.src.push_str("pub(crate) ");
802                    self.src.push_str(&handle.to_snake_case());
803                    self.src
804                        .push_str("_table: wit_bindgen_host_wasmer_rust::Table<T::");
805                    self.src.push_str(&handle.to_camel_case());
806                    self.src.push_str(">,\n");
807                }
808                self.src.push_str("}\n");
809                self.src.push_str("impl<T: ");
810                self.src.push_str(&module_camel);
811                self.src.push_str("> Default for ");
812                self.src.push_str(&module_camel);
813                self.src.push_str("Tables<T> {\n");
814                self.src.push_str("fn default() -> Self { Self {");
815                for handle in self.all_needed_handles.iter() {
816                    self.src.push_str(&handle.to_snake_case());
817                    self.src.push_str("_table: Default::default(),");
818                }
819                self.src.push_str("}}}");
820                self.src.push_str("impl<T: ");
821                self.src.push_str(&module_camel);
822                self.src.push_str("> Clone for ");
823                self.src.push_str(&module_camel);
824                self.src.push_str("Tables<T> {\n");
825                self.src.push_str("fn clone(&self) -> Self {\n");
826                self.src.push_str("Self::default()\n");
827                self.src.push_str("}}\n");
828            }
829        }
830
831        self.needs_lazy_initialized |= self.needs_memory;
832        self.needs_lazy_initialized |= !self.needs_functions.is_empty();
833        for (module, funcs) in mem::take(&mut self.guest_imports) {
834            let module_camel = module.to_camel_case();
835
836            if self.needs_lazy_initialized {
837                self.push_str("pub struct LazyInitialized {\n");
838                if self.needs_memory {
839                    self.push_str("memory: wasmer::Memory,\n");
840                }
841                for (name, func) in &self.needs_functions {
842                    self.src.push_str(&format!(
843                        "func_{name}: wasmer::TypedFunction<{cvt}>,\n",
844                        name = name,
845                        cvt = func.cvt(),
846                    ));
847                }
848                self.push_str("}\n");
849            }
850
851            self.push_str("\n#[must_use = \"The returned initializer function must be called\n");
852            self.push_str("with the instance and the store before starting the runtime\"]\n");
853            self.push_str("pub fn add_to_imports<T>(store: &mut wasmer::Store, imports: &mut wasmer::Imports, data: T)\n");
854            self.push_str("-> impl FnOnce(&wasmer::Instance, &dyn wasmer::AsStoreRef) -> Result<(), anyhow::Error>\n");
855            self.push_str("where T: ");
856            self.push_str(&module_camel);
857            self.push_str("\n{\n");
858
859            self.push_str("#[derive(Clone)]");
860            self.push_str("struct EnvWrapper<T: ");
861            self.push_str(&module_camel);
862            self.push_str("> {\n");
863            self.push_str("data: T,\n");
864            if !self.all_needed_handles.is_empty() {
865                self.push_str("tables: std::rc::Rc<core::cell::RefCell<");
866                self.push_str(&module_camel);
867                self.push_str("Tables<T>>>,\n");
868            }
869            if self.needs_lazy_initialized {
870                self.push_str("lazy: std::rc::Rc<OnceCell<LazyInitialized>>,\n");
871            }
872            self.push_str("}\n");
873            self.push_str("unsafe impl<T: ");
874            self.push_str(&module_camel);
875            self.push_str("> Send for EnvWrapper<T> {}\n");
876            self.push_str("unsafe impl<T: ");
877            self.push_str(&module_camel);
878            self.push_str("> Sync for EnvWrapper<T> {}\n");
879
880            if self.needs_lazy_initialized {
881                self.push_str("let lazy = std::rc::Rc::new(OnceCell::new());\n");
882            }
883
884            self.push_str("let env = EnvWrapper {\n");
885            self.push_str("data,\n");
886            if self.all_needed_handles.len() > 0 {
887                self.push_str("tables: std::rc::Rc::default(),\n");
888            }
889            if self.needs_lazy_initialized {
890                self.push_str("lazy: std::rc::Rc::clone(&lazy),\n");
891            }
892            self.push_str("};\n");
893            self.push_str("let env = wasmer::FunctionEnv::new(&mut *store, env);\n");
894            self.push_str("let mut exports = wasmer::Exports::new();\n");
895            self.push_str("let mut store = store.as_store_mut();\n");
896
897            for f in funcs {
898                self.push_str(&format!(
899                    "exports.insert(
900                        \"{}\",
901                        wasmer::Function::new_typed_with_env(
902                            &mut store,
903                            &env,
904                            {}
905                    ));\n",
906                    f.name, f.closure,
907                ));
908            }
909            self.push_str(&format!(
910                "imports.register_namespace(\"{}\", exports);\n",
911                module
912            ));
913
914            if !self.all_needed_handles.is_empty() {
915                self.push_str("let mut canonical_abi = imports.get_namespace_exports(\"canonical_abi\").unwrap_or_else(wasmer::Exports::new);\n");
916                for handle in self.all_needed_handles.iter() {
917                    self.src.push_str(&format!(
918                        "canonical_abi.insert(
919                            \"resource_drop_{name}\",
920                            wasmer::Function::new_typed_with_env(
921                                &mut store,
922                                &env,
923                                move |mut store: wasmer::FunctionEnvMut<EnvWrapper<T>>, handle: u32| -> Result<(), wasmer::RuntimeError> {{
924                                    let data_mut = store.data_mut();
925                                    let mut tables = data_mut.tables.borrow_mut();
926                                    let handle = tables
927                                        .{snake}_table
928                                        .remove(handle)
929                                        .map_err(|e| {{
930                                            wasmer::RuntimeError::new(format!(\"failed to remove handle: {{}}\", e))
931                                        }})?;
932                                    let host = &mut data_mut.data;
933                                    host.drop_{snake}(handle);
934                                    Ok(())
935                                }}
936                            )
937                        );\n",
938                        name = handle,
939                        snake = handle.to_snake_case(),
940                    ));
941                }
942                self.push_str("imports.register_namespace(\"canonical_abi\", canonical_abi);\n");
943            }
944
945            self.push_str(
946                "move |_instance: &wasmer::Instance, _store: &dyn wasmer::AsStoreRef| {\n",
947            );
948            if self.needs_lazy_initialized {
949                if self.needs_memory {
950                    self.push_str(
951                        "let memory = _instance.exports.get_memory(\"memory\")?.clone();\n",
952                    );
953                }
954                for name in self.needs_functions.keys() {
955                    self.src.push_str(&format!(
956                        "let func_{name} = _instance
957                        .exports
958                        .get_typed_function(
959                            &_store.as_store_ref(),
960                            \"{name}\",
961                        )
962                        .unwrap()
963                        .clone();\n"
964                    ));
965                }
966                self.push_str("lazy.set(LazyInitialized {\n");
967                if self.needs_memory {
968                    self.push_str("memory,\n");
969                }
970                for name in self.needs_functions.keys() {
971                    self.src.push_str(&format!("func_{name},\n"));
972                }
973                self.push_str("})\n");
974                self.push_str(
975                    ".map_err(|_e| anyhow::anyhow!(\"Couldn't set lazy initialized data\"))?;\n",
976                );
977            }
978            self.push_str("Ok(())\n");
979            self.push_str("}\n");
980
981            self.push_str("}\n");
982        }
983
984        for (module, exports) in sorted_iter(&mem::take(&mut self.guest_exports)) {
985            let name = module.to_camel_case();
986
987            // Generate a struct that is the "state" of this exported module
988            // which is held internally.
989            self.push_str(
990                "
991                /// Auxiliary data associated with the wasm exports.
992                ",
993            );
994            self.push_str("#[derive(Default)]\n");
995            self.push_str("pub struct ");
996            self.push_str(&name);
997            self.push_str("Data {\n");
998            for r in self.exported_resources.iter() {
999                self.src.push_str(&format!(
1000                    "
1001                        index_slab{idx}: wit_bindgen_host_wasmer_rust::rt::IndexSlab,
1002                        resource_slab{idx}: wit_bindgen_host_wasmer_rust::rt::ResourceSlab,
1003                        dtor{idx}: OnceCell<wasmer::TypedFunction<i32, ()>>,
1004                    ",
1005                    idx = r.index(),
1006                ));
1007            }
1008            self.push_str("}\n\n");
1009
1010            self.push_str("pub struct ");
1011            self.push_str(&name);
1012            self.push_str(" {\n");
1013            self.push_str("#[allow(dead_code)]\n");
1014            self.push_str(&format!("env: wasmer::FunctionEnv<{}Data>,\n", name));
1015            for (name, (ty, _)) in exports.fields.iter() {
1016                self.push_str(name);
1017                self.push_str(": ");
1018                self.push_str(ty);
1019                self.push_str(",\n");
1020            }
1021            self.push_str("}\n");
1022            self.push_str(&format!("impl {} {{\n", name));
1023
1024            if self.exported_resources.len() == 0 {
1025                self.push_str("#[allow(unused_variables)]\n");
1026            }
1027            self.push_str(&format!(
1028                "
1029                    /// Adds any intrinsics, if necessary for this exported wasm
1030                    /// functionality to the `ImportObject` provided.
1031                    ///
1032                    /// This function returns the `{0}Data` which needs to be
1033                    /// passed through to `{0}::new`.
1034                    fn add_to_imports(
1035                        mut store: impl wasmer::AsStoreMut,
1036                        imports: &mut wasmer::Imports,
1037                    ) -> wasmer::FunctionEnv<{0}Data> {{
1038                ",
1039                name,
1040            ));
1041            self.push_str(&format!(
1042                "let env = wasmer::FunctionEnv::new(&mut store, {name}Data::default());\n"
1043            ));
1044            if !self.all_needed_handles.is_empty() {
1045                self.push_str("let mut canonical_abi = imports.get_namespace_exports(\"canonical_abi\").unwrap_or_else(wasmer::Exports::new);\n");
1046                for r in self.exported_resources.iter() {
1047                    self.src.push_str(&format!(
1048                        "
1049                        canonical_abi.insert(
1050                            \"resource_drop_{resource}\",
1051                            wasmer::Function::new_typed_with_env(
1052                                &mut store,
1053                                &env,
1054                                move |mut store: wasmer::FunctionEnvMut<{name}Data>, idx: u32| -> Result<(), wasmer::RuntimeError> {{
1055                                    let resource_idx = store.data_mut().index_slab{idx}.remove(idx)?;
1056                                    let wasm = match store.data_mut().resource_slab{idx}.drop(resource_idx) {{
1057                                        Some(wasm) => wasm,
1058                                        None => return Ok(()),
1059                                    }};
1060                                    let dtor = store.data_mut().dtor{idx}.get().unwrap().clone();
1061                                    dtor.call(&mut store, wasm)?;
1062                                    Ok(())
1063                                }},
1064                            )
1065                        );
1066                        canonical_abi.insert(
1067                            \"resource_clone_{resource}\",
1068                            wasmer::Function::new_typed_with_env(
1069                                &mut store,
1070                                &env,
1071                                move |mut store: wasmer::FunctionEnvMut<{name}Data>, idx: u32| -> Result<u32, wasmer::RuntimeError>  {{
1072                                    let state = &mut *store.data_mut();
1073                                    let resource_idx = state.index_slab{idx}.get(idx)?;
1074                                    state.resource_slab{idx}.clone(resource_idx)?;
1075                                    Ok(state.index_slab{idx}.insert(resource_idx))
1076                                }},
1077                            )
1078                        );
1079                        canonical_abi.insert(
1080                            \"resource_get_{resource}\",
1081                            wasmer::Function::new_typed_with_env(
1082                                &mut store,
1083                                &env,
1084                                move |mut store: wasmer::FunctionEnvMut<{name}Data>, idx: u32| -> Result<i32, wasmer::RuntimeError>  {{
1085                                    let state = &mut *store.data_mut();
1086                                    let resource_idx = state.index_slab{idx}.get(idx)?;
1087                                    Ok(state.resource_slab{idx}.get(resource_idx))
1088                                }},
1089                            )
1090                        );
1091                        canonical_abi.insert(
1092                            \"resource_new_{resource}\",
1093                            wasmer::Function::new_typed_with_env(
1094                                &mut store,
1095                                &env,
1096                                move |mut store: wasmer::FunctionEnvMut<{name}Data>, val: i32| -> Result<u32, wasmer::RuntimeError>  {{
1097                                    let state = &mut *store.data_mut();
1098                                    let resource_idx = state.resource_slab{idx}.insert(val);
1099                                    Ok(state.index_slab{idx}.insert(resource_idx))
1100                                }},
1101                            )
1102                        );
1103                    ",
1104                        name = name,
1105                        resource = iface.resources[*r].name,
1106                        idx = r.index(),
1107                    ));
1108                }
1109                self.push_str("imports.register_namespace(\"canonical_abi\", canonical_abi);\n");
1110            }
1111            self.push_str("env\n");
1112            self.push_str("}\n");
1113
1114            self.push_str(&format!(
1115                "
1116                    /// Instantiates the provided `module` using the specified
1117                    /// parameters, wrapping up the result in a structure that
1118                    /// translates between wasm and the host.
1119                    ///
1120                    /// The `imports` provided will have intrinsics added to it
1121                    /// automatically, so it's not necessary to call
1122                    /// `add_to_imports` beforehand. This function will
1123                    /// instantiate the `module` otherwise using `imports`, and
1124                    /// both an instance of this structure and the underlying
1125                    /// `wasmer::Instance` will be returned.
1126                    pub fn instantiate(
1127                        mut store: impl wasmer::AsStoreMut,
1128                        module: &wasmer::Module,
1129                        imports: &mut wasmer::Imports,
1130                    ) -> anyhow::Result<(Self, wasmer::Instance)> {{
1131                        let env = Self::add_to_imports(&mut store, imports);
1132                        let instance = wasmer::Instance::new(
1133                            &mut store, module, &*imports)?;
1134                        "
1135            ));
1136            if !self.exported_resources.is_empty() {
1137                self.push_str("{\n");
1138                for r in self.exported_resources.iter() {
1139                    self.src.push_str(&format!(
1140                        "let dtor{idx} = instance
1141                                .exports
1142                                .get_typed_function(
1143                                    &store,
1144                                    \"canonical_abi_drop_{name}\",
1145                                )?
1146                                .clone();
1147                                ",
1148                        name = iface.resources[*r].name,
1149                        idx = r.index(),
1150                    ));
1151                }
1152                self.push_str("\n");
1153
1154                for r in self.exported_resources.iter() {
1155                    self.src.push_str(&format!(
1156                            "env
1157                                .as_mut(&mut store)
1158                                .dtor{idx}
1159                                .set(dtor{idx})
1160                                .map_err(|_e| anyhow::anyhow!(\"Couldn't set canonical_abi_drop_{name}\"))?;
1161                                ",
1162                                name = iface.resources[*r].name,
1163                                idx = r.index(),
1164                                ));
1165                }
1166                self.push_str("}\n");
1167            }
1168            self.push_str(&format!(
1169                "
1170                        Ok((Self::new(store, &instance, env)?, instance))
1171                    }}
1172                ",
1173            ));
1174
1175            self.push_str(&format!(
1176                "
1177                    /// Low-level creation wrapper for wrapping up the exports
1178                    /// of the `instance` provided in this structure of wasm
1179                    /// exports.
1180                    ///
1181                    /// This function will extract exports from the `instance`
1182                    /// and wrap them all up in the returned structure which can
1183                    /// be used to interact with the wasm module.
1184                    pub fn new(
1185                        store: impl wasmer::AsStoreMut,
1186                        _instance: &wasmer::Instance,
1187                        env: wasmer::FunctionEnv<{}Data>,
1188                    ) -> Result<Self, wasmer::ExportError> {{
1189                ",
1190                name,
1191            ));
1192            //assert!(!self.needs_get_func);
1193            for (name, (_, get)) in exports.fields.iter() {
1194                self.push_str("let ");
1195                self.push_str(&name);
1196                self.push_str("= ");
1197                self.push_str(&get);
1198                self.push_str(";\n");
1199            }
1200            self.push_str("Ok(");
1201            self.push_str(&name);
1202            self.push_str("{\n");
1203            for (name, _) in exports.fields.iter() {
1204                self.push_str(name);
1205                self.push_str(",\n");
1206            }
1207            self.push_str("env,\n");
1208            self.push_str("})\n");
1209            self.push_str("}\n");
1210
1211            for func in exports.funcs.iter() {
1212                self.push_str(func);
1213            }
1214
1215            for r in self.exported_resources.iter() {
1216                self.src.push_str(&format!(
1217                    "
1218                        /// Drops the host-owned handle to the resource
1219                        /// specified.
1220                        ///
1221                        /// Note that this may execute the WebAssembly-defined
1222                        /// destructor for this type. This also may not run
1223                        /// the destructor if there are still other references
1224                        /// to this type.
1225                        pub fn drop_{name_snake}(
1226                            &self,
1227                            store: &mut wasmer::Store,
1228                            val: {name_camel},
1229                        ) -> Result<(), wasmer::RuntimeError> {{
1230                            let state = self.env.as_mut(store);
1231                            let wasm = match state.resource_slab{idx}.drop(val.0) {{
1232                                Some(val) => val,
1233                                None => return Ok(()),
1234                            }};
1235                            let dtor{idx} = state.dtor{idx}.get().unwrap().clone();
1236                            dtor{idx}.call(store, wasm)?;
1237                            Ok(())
1238                        }}
1239                    ",
1240                    name_snake = iface.resources[*r].name.to_snake_case(),
1241                    name_camel = iface.resources[*r].name.to_camel_case(),
1242                    idx = r.index(),
1243                ));
1244            }
1245
1246            self.push_str("}\n");
1247        }
1248        self.print_intrinsics();
1249
1250        // Close the opening `mod`.
1251        self.push_str("}\n");
1252
1253        let mut src = mem::take(&mut self.src);
1254        if self.opts.rustfmt {
1255            let mut child = Command::new("rustfmt")
1256                .arg("--edition=2018")
1257                .stdin(Stdio::piped())
1258                .stdout(Stdio::piped())
1259                .spawn()
1260                .expect("failed to spawn `rustfmt`");
1261            child
1262                .stdin
1263                .take()
1264                .unwrap()
1265                .write_all(src.as_bytes())
1266                .unwrap();
1267            src.as_mut_string().truncate(0);
1268            child
1269                .stdout
1270                .take()
1271                .unwrap()
1272                .read_to_string(src.as_mut_string())
1273                .unwrap();
1274            let status = child.wait().unwrap();
1275            assert!(status.success());
1276        }
1277
1278        files.push("bindings.rs", src.as_bytes());
1279    }
1280}
1281
1282struct FunctionBindgen<'a> {
1283    gen: &'a mut Wasmer,
1284
1285    // Number used to assign unique names to temporary variables.
1286    tmp: usize,
1287
1288    // Destination where source code is pushed onto for this function
1289    src: Source,
1290
1291    // The named parameters that are available to this function
1292    params: Vec<String>,
1293
1294    // Management of block scopes used by `Bindgen`.
1295    block_storage: Vec<Source>,
1296    blocks: Vec<String>,
1297
1298    // Whether or not the code generator is after the invocation of wasm or the
1299    // host, used for knowing where to acquire memory from.
1300    after_call: bool,
1301    // Whether or not the `caller_memory` variable has been defined and is
1302    // available for use.
1303    caller_memory_available: bool,
1304    // Code that must be executed before a return, generated during instruction
1305    // lowering.
1306    cleanup: Option<String>,
1307
1308    // Rust clousures for buffers that must be placed at the front of the
1309    // function.
1310    closures: Source,
1311
1312    // Various intrinsic properties this function's codegen required, must be
1313    // satisfied in the function header if any are set.
1314    needs_buffer_transaction: bool,
1315    needs_borrow_checker: bool,
1316    needs_memory: bool,
1317    needs_functions: HashMap<String, NeededFunction>,
1318}
1319
1320impl FunctionBindgen<'_> {
1321    fn new(gen: &mut Wasmer, params: Vec<String>) -> FunctionBindgen<'_> {
1322        FunctionBindgen {
1323            gen,
1324            block_storage: Vec::new(),
1325            blocks: Vec::new(),
1326            src: Source::default(),
1327            after_call: false,
1328            caller_memory_available: false,
1329            tmp: 0,
1330            cleanup: None,
1331            closures: Source::default(),
1332            needs_buffer_transaction: false,
1333            needs_borrow_checker: false,
1334            needs_memory: false,
1335            needs_functions: HashMap::new(),
1336            params,
1337        }
1338    }
1339
1340    fn memory_src(&mut self) -> String {
1341        if self.gen.in_import {
1342            if !self.after_call {
1343                // Before calls we use `_bc` which is a borrow checker used for
1344                // getting long-lasting borrows into memory.
1345                self.needs_borrow_checker = true;
1346                return format!("_bc");
1347            }
1348
1349            if !self.caller_memory_available {
1350                self.needs_memory = true;
1351                self.caller_memory_available = true;
1352                self.push_str("let _memory_view = _memory.view(&store);\n");
1353                self.push_str(
1354                    "let caller_memory = unsafe { _memory_view.data_unchecked_mut() };\n",
1355                );
1356            }
1357            format!("caller_memory")
1358        } else {
1359            self.needs_memory = true;
1360            self.push_str("let _memory_view = _memory.view(&store);\n");
1361            format!("unsafe {{ _memory_view.data_unchecked_mut() }}")
1362        }
1363    }
1364
1365    fn call_intrinsic(&mut self, name: &str, args: String) {
1366        self.push_str(&format!("func_{name}.call({args})?;\n"));
1367        self.caller_memory_available = false; // invalidated by call
1368    }
1369
1370    fn load(&mut self, offset: i32, ty: &str, operands: &[String]) -> String {
1371        let mem = self.memory_src();
1372        self.gen.needs_raw_mem = true;
1373        let tmp = self.tmp();
1374        self.push_str(&format!(
1375            "let load{} = {}.load::<{}>({} + {})?;\n",
1376            tmp, mem, ty, operands[0], offset
1377        ));
1378        format!("load{}", tmp)
1379    }
1380
1381    fn store(&mut self, offset: i32, method: &str, extra: &str, operands: &[String]) {
1382        let mem = self.memory_src();
1383        self.gen.needs_raw_mem = true;
1384        self.push_str(&format!(
1385            "{}.store({} + {}, wit_bindgen_host_wasmer_rust::rt::{}({}){})?;\n",
1386            mem, operands[1], offset, method, operands[0], extra
1387        ));
1388    }
1389}
1390
1391impl RustFunctionGenerator for FunctionBindgen<'_> {
1392    fn push_str(&mut self, s: &str) {
1393        self.src.push_str(s);
1394    }
1395
1396    fn tmp(&mut self) -> usize {
1397        let ret = self.tmp;
1398        self.tmp += 1;
1399        ret
1400    }
1401
1402    fn rust_gen(&self) -> &dyn RustGenerator {
1403        self.gen
1404    }
1405
1406    fn lift_lower(&self) -> LiftLower {
1407        if self.gen.in_import {
1408            LiftLower::LiftArgsLowerResults
1409        } else {
1410            LiftLower::LowerArgsLiftResults
1411        }
1412    }
1413}
1414
1415impl Bindgen for FunctionBindgen<'_> {
1416    type Operand = String;
1417
1418    fn sizes(&self) -> &SizeAlign {
1419        &self.gen.sizes
1420    }
1421
1422    fn push_block(&mut self) {
1423        let prev = mem::take(&mut self.src);
1424        self.block_storage.push(prev);
1425    }
1426
1427    fn finish_block(&mut self, operands: &mut Vec<String>) {
1428        let to_restore = self.block_storage.pop().unwrap();
1429        let src = mem::replace(&mut self.src, to_restore);
1430        let expr = match operands.len() {
1431            0 => "()".to_string(),
1432            1 => operands[0].clone(),
1433            _ => format!("({})", operands.join(", ")),
1434        };
1435        if src.is_empty() {
1436            self.blocks.push(expr);
1437        } else if operands.is_empty() {
1438            self.blocks.push(format!("{{\n{}}}", &src[..]));
1439        } else {
1440            self.blocks.push(format!("{{\n{}{}\n}}", &src[..], expr));
1441        }
1442        self.caller_memory_available = false;
1443    }
1444
1445    fn return_pointer(&mut self, _iface: &Interface, _size: usize, _align: usize) -> String {
1446        unimplemented!()
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        let mut top_as = |cvt: &str| {
1461            let mut s = operands.pop().unwrap();
1462            s.push_str(" as ");
1463            s.push_str(cvt);
1464            results.push(s);
1465        };
1466
1467        let mut try_from = |cvt: &str, operands: &[String], results: &mut Vec<String>| {
1468            self.gen.needs_bad_int = true;
1469            let result = format!("{}::try_from({}).map_err(bad_int)?", cvt, operands[0]);
1470            results.push(result);
1471        };
1472
1473        match inst {
1474            Instruction::GetArg { nth } => results.push(self.params[*nth].clone()),
1475            Instruction::I32Const { val } => results.push(format!("{}i32", val)),
1476            Instruction::ConstZero { tys } => {
1477                for ty in tys.iter() {
1478                    match ty {
1479                        WasmType::I32 => results.push("0i32".to_string()),
1480                        WasmType::I64 => results.push("0i64".to_string()),
1481                        WasmType::F32 => results.push("0.0f32".to_string()),
1482                        WasmType::F64 => results.push("0.0f64".to_string()),
1483                    }
1484                }
1485            }
1486
1487            Instruction::I64FromU64 | Instruction::I64FromS64 => {
1488                let s = operands.pop().unwrap();
1489                results.push(format!("wit_bindgen_host_wasmer_rust::rt::as_i64({})", s));
1490            }
1491            Instruction::I32FromChar
1492            | Instruction::I32FromU8
1493            | Instruction::I32FromS8
1494            | Instruction::I32FromU16
1495            | Instruction::I32FromS16
1496            | Instruction::I32FromU32
1497            | Instruction::I32FromS32 => {
1498                let s = operands.pop().unwrap();
1499                results.push(format!("wit_bindgen_host_wasmer_rust::rt::as_i32({})", s));
1500            }
1501
1502            Instruction::F32FromFloat32
1503            | Instruction::F64FromFloat64
1504            | Instruction::Float32FromF32
1505            | Instruction::Float64FromF64
1506            | Instruction::S32FromI32
1507            | Instruction::S64FromI64 => {
1508                results.push(operands.pop().unwrap());
1509            }
1510
1511            // Downcasts from `i32` into smaller integers are checked to ensure
1512            // that they fit within the valid range. While not strictly
1513            // necessary since we could chop bits off this should be more
1514            // forward-compatible with any future changes.
1515            Instruction::S8FromI32 => try_from("i8", operands, results),
1516            Instruction::U8FromI32 => try_from("u8", operands, results),
1517            Instruction::S16FromI32 => try_from("i16", operands, results),
1518            Instruction::U16FromI32 => try_from("u16", operands, results),
1519
1520            // Casts of the same bit width simply use `as` since we're just
1521            // reinterpreting the bits already there.
1522            Instruction::U32FromI32 => top_as("u32"),
1523            Instruction::U64FromI64 => top_as("u64"),
1524
1525            Instruction::CharFromI32 => {
1526                self.gen.needs_char_from_i32 = true;
1527                results.push(format!("char_from_i32({})?", operands[0]));
1528            }
1529
1530            Instruction::Bitcasts { casts } => {
1531                wit_bindgen_gen_rust_lib::bitcast(casts, operands, results)
1532            }
1533
1534            Instruction::UnitLower => {
1535                self.push_str(&format!("let () = {};\n", operands[0]));
1536            }
1537            Instruction::UnitLift => {
1538                results.push("()".to_string());
1539            }
1540
1541            Instruction::I32FromBool => {
1542                results.push(format!("match {} {{ true => 1, false => 0 }}", operands[0]));
1543            }
1544            Instruction::BoolFromI32 => {
1545                self.gen.needs_invalid_variant = true;
1546                results.push(format!(
1547                    "match {} {{
1548                        0 => false,
1549                        1 => true,
1550                        _ => return Err(invalid_variant(\"bool\")),
1551                    }}",
1552                    operands[0],
1553                ));
1554            }
1555
1556            Instruction::I32FromOwnedHandle { ty } => {
1557                let name = &iface.resources[*ty].name;
1558                results.push(format!(
1559                    "{{
1560                        let data_mut = store.data_mut();
1561                        let mut tables = data_mut.tables.borrow_mut();
1562                        tables.{}_table.insert({}) as i32
1563                    }}",
1564                    name.to_snake_case(),
1565                    operands[0]
1566                ));
1567            }
1568            Instruction::HandleBorrowedFromI32 { ty } => {
1569                let name = &iface.resources[*ty].name;
1570                results.push(format!(
1571                    "tables
1572                        .{}_table
1573                        .get(({}) as u32)
1574                        .ok_or_else(|| {{
1575                            wasmer::RuntimeError::new(\"invalid handle index\")
1576                        }})?",
1577                    name.to_snake_case(),
1578                    operands[0]
1579                ));
1580            }
1581            Instruction::I32FromBorrowedHandle { ty } => {
1582                let tmp = self.tmp();
1583                self.push_str(&format!(
1584                    "
1585                        let obj{tmp} = {op};
1586                        let handle{tmp} = {{
1587                            let state = self.env.as_mut(store);
1588                            state.resource_slab{idx}.clone(obj{tmp}.0)?;
1589                            state.index_slab{idx}.insert(obj{tmp}.0)
1590                        }};
1591                    ",
1592                    tmp = tmp,
1593                    idx = ty.index(),
1594                    op = operands[0],
1595                ));
1596
1597                results.push(format!("handle{} as i32", tmp,));
1598            }
1599            Instruction::HandleOwnedFromI32 { ty } => {
1600                let tmp = self.tmp();
1601                self.push_str(&format!(
1602                    "let state = self.env.as_mut(store);
1603                    let handle{} = state.index_slab{}.remove({} as u32)?;\n",
1604                    tmp,
1605                    ty.index(),
1606                    operands[0],
1607                ));
1608
1609                let name = iface.resources[*ty].name.to_camel_case();
1610                results.push(format!("{}(handle{})", name, tmp));
1611            }
1612
1613            Instruction::RecordLower { ty, record, .. } => {
1614                self.record_lower(iface, *ty, record, &operands[0], results);
1615            }
1616            Instruction::RecordLift { ty, record, .. } => {
1617                self.record_lift(iface, *ty, record, operands, results);
1618            }
1619
1620            Instruction::TupleLower { tuple, .. } => {
1621                self.tuple_lower(tuple, &operands[0], results);
1622            }
1623            Instruction::TupleLift { .. } => {
1624                self.tuple_lift(operands, results);
1625            }
1626
1627            Instruction::FlagsLower { flags, .. } => {
1628                let tmp = self.tmp();
1629                self.push_str(&format!("let flags{} = {};\n", tmp, operands[0]));
1630                for i in 0..flags.repr().count() {
1631                    results.push(format!("(flags{}.bits >> {}) as i32", tmp, i * 32));
1632                }
1633            }
1634            Instruction::FlagsLift { flags, name, .. } => {
1635                self.gen.needs_validate_flags = true;
1636                let repr = RustFlagsRepr::new(flags);
1637                let mut flags = String::from("0");
1638                for (i, op) in operands.iter().enumerate() {
1639                    flags.push_str(&format!("| (({} as {repr}) << {})", op, i * 32));
1640                }
1641                results.push(format!(
1642                    "validate_flags(
1643                        {},
1644                        {name}::all().bits(),
1645                        \"{name}\",
1646                        |bits| {name} {{ bits }}
1647                    )?",
1648                    flags,
1649                    name = name.to_camel_case(),
1650                ));
1651            }
1652
1653            Instruction::VariantPayloadName => results.push("e".to_string()),
1654
1655            Instruction::VariantLower {
1656                variant,
1657                results: result_types,
1658                ty,
1659                ..
1660            } => {
1661                let blocks = self
1662                    .blocks
1663                    .drain(self.blocks.len() - variant.cases.len()..)
1664                    .collect::<Vec<_>>();
1665                self.let_results(result_types.len(), results);
1666                let op0 = &operands[0];
1667                self.push_str(&format!("match {op0} {{\n"));
1668                let name = self.typename_lower(iface, *ty);
1669                for (case, block) in variant.cases.iter().zip(blocks) {
1670                    let case_name = case.name.to_camel_case();
1671                    self.push_str(&format!("{name}::{case_name}"));
1672                    if case.ty == Type::Unit {
1673                        self.push_str(&format!(" => {{\nlet e = ();\n{block}\n}}\n"));
1674                    } else {
1675                        self.push_str(&format!("(e) => {block},\n"));
1676                    }
1677                }
1678                self.push_str("};\n");
1679            }
1680
1681            Instruction::VariantLift { variant, ty, .. } => {
1682                let blocks = self
1683                    .blocks
1684                    .drain(self.blocks.len() - variant.cases.len()..)
1685                    .collect::<Vec<_>>();
1686                let op0 = &operands[0];
1687                let mut result = format!("match {op0} {{\n");
1688                let name = self.typename_lift(iface, *ty);
1689                for (i, (case, block)) in variant.cases.iter().zip(blocks).enumerate() {
1690                    let block = if case.ty != Type::Unit {
1691                        format!("({block})")
1692                    } else {
1693                        String::new()
1694                    };
1695                    let case = case.name.to_camel_case();
1696                    result.push_str(&format!("{i} => {name}::{case}{block},\n"));
1697                }
1698                result.push_str(&format!("_ => return Err(invalid_variant(\"{name}\")),\n"));
1699                result.push_str("}");
1700                results.push(result);
1701                self.gen.needs_invalid_variant = true;
1702            }
1703
1704            Instruction::UnionLower {
1705                union,
1706                results: result_types,
1707                ty,
1708                ..
1709            } => {
1710                let blocks = self
1711                    .blocks
1712                    .drain(self.blocks.len() - union.cases.len()..)
1713                    .collect::<Vec<_>>();
1714                self.let_results(result_types.len(), results);
1715                let op0 = &operands[0];
1716                self.push_str(&format!("match {op0} {{\n"));
1717                let name = self.typename_lower(iface, *ty);
1718                for (case_name, block) in self
1719                    .gen
1720                    .union_case_names(iface, union)
1721                    .into_iter()
1722                    .zip(blocks)
1723                {
1724                    self.push_str(&format!("{name}::{case_name}(e) => {block},\n"));
1725                }
1726                self.push_str("};\n");
1727            }
1728
1729            Instruction::UnionLift { union, ty, .. } => {
1730                let blocks = self
1731                    .blocks
1732                    .drain(self.blocks.len() - union.cases.len()..)
1733                    .collect::<Vec<_>>();
1734                let op0 = &operands[0];
1735                let mut result = format!("match {op0} {{\n");
1736                let name = self.typename_lift(iface, *ty);
1737                for (i, (case_name, block)) in self
1738                    .gen
1739                    .union_case_names(iface, union)
1740                    .into_iter()
1741                    .zip(blocks)
1742                    .enumerate()
1743                {
1744                    result.push_str(&format!("{i} => {name}::{case_name}({block}),\n"));
1745                }
1746                result.push_str(&format!("_ => return Err(invalid_variant(\"{name}\")),\n"));
1747                result.push_str("}");
1748                results.push(result);
1749            }
1750
1751            Instruction::OptionLower {
1752                results: result_types,
1753                ..
1754            } => {
1755                let some = self.blocks.pop().unwrap();
1756                let none = self.blocks.pop().unwrap();
1757                self.let_results(result_types.len(), results);
1758                let operand = &operands[0];
1759                self.push_str(&format!(
1760                    "match {operand} {{
1761                        Some(e) => {some},
1762                        None => {{\nlet e = ();\n{none}\n}},
1763                    }};"
1764                ));
1765            }
1766
1767            Instruction::OptionLift { .. } => {
1768                let some = self.blocks.pop().unwrap();
1769                let none = self.blocks.pop().unwrap();
1770                assert_eq!(none, "()");
1771                let operand = &operands[0];
1772                results.push(format!(
1773                    "match {operand} {{
1774                        0 => None,
1775                        1 => Some({some}),
1776                        _ => return Err(invalid_variant(\"option\")),
1777                    }}"
1778                ));
1779                self.gen.needs_invalid_variant = true;
1780            }
1781
1782            Instruction::ResultLower {
1783                results: result_types,
1784                ..
1785            } => {
1786                let err = self.blocks.pop().unwrap();
1787                let ok = self.blocks.pop().unwrap();
1788                self.let_results(result_types.len(), results);
1789                let operand = &operands[0];
1790                self.push_str(&format!(
1791                    "match {operand} {{
1792                        Ok(e) => {{ {ok} }},
1793                        Err(e) => {{ {err} }},
1794                    }};"
1795                ));
1796            }
1797
1798            Instruction::ResultLift { .. } => {
1799                let err = self.blocks.pop().unwrap();
1800                let ok = self.blocks.pop().unwrap();
1801                let operand = &operands[0];
1802                results.push(format!(
1803                    "match {operand} {{
1804                        0 => Ok({ok}),
1805                        1 => Err({err}),
1806                        _ => return Err(invalid_variant(\"result\")),
1807                    }}"
1808                ));
1809                self.gen.needs_invalid_variant = true;
1810            }
1811
1812            Instruction::EnumLower { .. } => {
1813                results.push(format!("{} as i32", operands[0]));
1814            }
1815
1816            Instruction::EnumLift { name, enum_, .. } => {
1817                let op0 = &operands[0];
1818                let mut result = format!("match {op0} {{\n");
1819                let name = name.to_camel_case();
1820                for (i, case) in enum_.cases.iter().enumerate() {
1821                    let case = case.name.to_camel_case();
1822                    result.push_str(&format!("{i} => {name}::{case},\n"));
1823                }
1824                result.push_str(&format!("_ => return Err(invalid_variant(\"{name}\")),\n"));
1825                result.push_str("}");
1826                results.push(result);
1827                self.gen.needs_invalid_variant = true;
1828            }
1829
1830            Instruction::ListCanonLower { element, realloc } => {
1831                // Lowering only happens when we're passing lists into wasm,
1832                // which forces us to always allocate, so this should always be
1833                // `Some`.
1834                let realloc = realloc.unwrap();
1835                self.needs_functions
1836                    .insert(realloc.to_string(), NeededFunction::Realloc);
1837                let (size, align) = (self.gen.sizes.size(element), self.gen.sizes.align(element));
1838
1839                // Store the operand into a temporary...
1840                let tmp = self.tmp();
1841                let val = format!("vec{}", tmp);
1842                self.push_str(&format!("let {} = {};\n", val, operands[0]));
1843
1844                // ... and then realloc space for the result in the guest module
1845                let ptr = format!("ptr{}", tmp);
1846                self.push_str(&format!("let {} = ", ptr));
1847                self.call_intrinsic(
1848                    realloc,
1849                    format!(
1850                        "&mut store.as_store_mut(), 0, 0, {}, ({}.len() as i32) * {}",
1851                        align, val, size
1852                    ),
1853                );
1854
1855                // ... and then copy over the result.
1856                let mem = self.memory_src();
1857                self.push_str(&format!("{}.store_many({}, &{})?;\n", mem, ptr, val));
1858                self.gen.needs_raw_mem = true;
1859                self.needs_memory = true;
1860                results.push(ptr);
1861                results.push(format!("{}.len() as i32", val));
1862            }
1863
1864            Instruction::ListCanonLift { element, free, .. } => match free {
1865                Some(free) => {
1866                    self.needs_memory = true;
1867                    self.gen.needs_copy_slice = true;
1868                    self.needs_functions
1869                        .insert(free.to_string(), NeededFunction::Free);
1870                    let align = self.gen.sizes.align(element);
1871                    let tmp = self.tmp();
1872                    self.push_str(&format!("let ptr{} = {};\n", tmp, operands[0]));
1873                    self.push_str(&format!("let len{} = {};\n", tmp, operands[1]));
1874                    let result = format!(
1875                        "
1876                                copy_slice(
1877                                    store,
1878                                    _memory,
1879                                    func_{},
1880                                    ptr{tmp}, len{tmp}, {}
1881                                )?
1882                            ",
1883                        free,
1884                        align,
1885                        tmp = tmp
1886                    );
1887                    results.push(result);
1888                }
1889                None => {
1890                    self.needs_borrow_checker = true;
1891                    let tmp = self.tmp();
1892                    self.push_str(&format!("let ptr{} = {};\n", tmp, operands[0]));
1893                    self.push_str(&format!("let len{} = {};\n", tmp, operands[1]));
1894                    let slice = format!("_bc.slice(ptr{0}, len{0})?", tmp);
1895                    results.push(slice);
1896                }
1897            },
1898
1899            Instruction::StringLower { realloc } => {
1900                // see above for this unwrap
1901                let realloc = realloc.unwrap();
1902                self.needs_functions
1903                    .insert(realloc.to_string(), NeededFunction::Realloc);
1904
1905                // Store the operand into a temporary...
1906                let tmp = self.tmp();
1907                let val = format!("vec{}", tmp);
1908                self.push_str(&format!("let {} = {};\n", val, operands[0]));
1909
1910                // ... and then realloc space for the result in the guest module
1911                let ptr = format!("ptr{}", tmp);
1912                self.push_str(&format!("let {} = ", ptr));
1913                self.call_intrinsic(
1914                    realloc,
1915                    format!("&mut store.as_store_mut(), 0, 0, 1, {}.len() as i32", val),
1916                );
1917
1918                // ... and then copy over the result.
1919                let mem = self.memory_src();
1920                self.push_str(&format!(
1921                    "{}.store_many({}, {}.as_bytes())?;\n",
1922                    mem, ptr, val
1923                ));
1924                self.gen.needs_raw_mem = true;
1925                self.needs_memory = true;
1926                results.push(ptr);
1927                results.push(format!("{}.len() as i32", val));
1928            }
1929
1930            Instruction::StringLift { free } => match free {
1931                Some(free) => {
1932                    self.needs_memory = true;
1933                    self.gen.needs_copy_slice = true;
1934                    self.needs_functions
1935                        .insert(free.to_string(), NeededFunction::Free);
1936                    let tmp = self.tmp();
1937                    self.push_str(&format!("let ptr{} = {};\n", tmp, operands[0]));
1938                    self.push_str(&format!("let len{} = {};\n", tmp, operands[1]));
1939                    self.push_str(&format!(
1940                        "
1941                            let data{tmp} = copy_slice(
1942                                store,
1943                                _memory,
1944                                func_{},
1945                                ptr{tmp}, len{tmp}, 1,
1946                            )?;
1947                        ",
1948                        free,
1949                        tmp = tmp,
1950                    ));
1951                    results.push(format!(
1952                        "String::from_utf8(data{})
1953                            .map_err(|_| wasmer::RuntimeError::new(\"invalid utf-8\"))?",
1954                        tmp,
1955                    ));
1956                }
1957                None => {
1958                    self.needs_borrow_checker = true;
1959                    let tmp = self.tmp();
1960                    self.push_str(&format!("let ptr{} = {};\n", tmp, operands[0]));
1961                    self.push_str(&format!("let len{} = {};\n", tmp, operands[1]));
1962                    let slice = format!("_bc.slice_str(ptr{0}, len{0})?", tmp);
1963                    results.push(slice);
1964                }
1965            },
1966
1967            Instruction::ListLower { element, realloc } => {
1968                let realloc = realloc.unwrap();
1969                let body = self.blocks.pop().unwrap();
1970                let tmp = self.tmp();
1971                let vec = format!("vec{}", tmp);
1972                let result = format!("result{}", tmp);
1973                let len = format!("len{}", tmp);
1974                self.needs_functions
1975                    .insert(realloc.to_string(), NeededFunction::Realloc);
1976                let size = self.gen.sizes.size(element);
1977                let align = self.gen.sizes.align(element);
1978
1979                // first store our vec-to-lower in a temporary since we'll
1980                // reference it multiple times.
1981                self.push_str(&format!("let {} = {};\n", vec, operands[0]));
1982                self.push_str(&format!("let {} = {}.len() as i32;\n", len, vec));
1983
1984                // ... then realloc space for the result in the guest module
1985                self.push_str(&format!("let {} = ", result));
1986                self.call_intrinsic(
1987                    realloc,
1988                    format!(
1989                        "&mut store.as_store_mut(), 0, 0, {}, {} * {}",
1990                        align, len, size
1991                    ),
1992                );
1993
1994                // ... then consume the vector and use the block to lower the
1995                // result.
1996                self.push_str(&format!(
1997                    "for (i, e) in {}.into_iter().enumerate() {{\n",
1998                    vec
1999                ));
2000                self.push_str(&format!("let base = {} + (i as i32) * {};\n", result, size));
2001                self.push_str(&body);
2002                self.push_str("}");
2003
2004                results.push(result);
2005                results.push(len);
2006            }
2007
2008            Instruction::ListLift { element, free, .. } => {
2009                let body = self.blocks.pop().unwrap();
2010                let tmp = self.tmp();
2011                let size = self.gen.sizes.size(element);
2012                let align = self.gen.sizes.align(element);
2013                let len = format!("len{}", tmp);
2014                self.push_str(&format!("let {} = {};\n", len, operands[1]));
2015                let base = format!("base{}", tmp);
2016                self.push_str(&format!("let {} = {};\n", base, operands[0]));
2017                let result = format!("result{}", tmp);
2018                self.push_str(&format!(
2019                    "let mut {} = Vec::with_capacity({} as usize);\n",
2020                    result, len,
2021                ));
2022
2023                self.push_str("for i in 0..");
2024                self.push_str(&len);
2025                self.push_str(" {\n");
2026                self.push_str("let base = ");
2027                self.push_str(&base);
2028                self.push_str(" + i *");
2029                self.push_str(&size.to_string());
2030                self.push_str(";\n");
2031                self.push_str(&result);
2032                self.push_str(".push(");
2033                self.push_str(&body);
2034                self.push_str(");\n");
2035                self.push_str("}\n");
2036                results.push(result);
2037
2038                if let Some(free) = free {
2039                    self.call_intrinsic(
2040                        free,
2041                        format!(
2042                            "&mut store.as_store_mut(), {}, {} * {}, {}",
2043                            base, len, size, align
2044                        ),
2045                    );
2046                    self.needs_functions
2047                        .insert(free.to_string(), NeededFunction::Free);
2048                }
2049            }
2050
2051            Instruction::IterElem { .. } => {
2052                self.caller_memory_available = false; // invalidated by for loop
2053                results.push("e".to_string())
2054            }
2055
2056            Instruction::IterBasePointer => results.push("base".to_string()),
2057
2058            Instruction::CallWasm {
2059                iface: _,
2060                base_name,
2061                mangled_name: _,
2062                sig,
2063            } => {
2064                if sig.results.len() > 0 {
2065                    let tmp = self.tmp();
2066                    if sig.results.len() == 1 {
2067                        self.push_str("let ");
2068                        let arg = format!("result{}", tmp);
2069                        self.push_str(&arg);
2070                        results.push(arg);
2071                        self.push_str(" = ");
2072                    } else {
2073                        self.push_str("let (");
2074                        for i in 0..sig.results.len() {
2075                            let arg = format!("result{}_{}", tmp, i);
2076                            self.push_str(&arg);
2077                            self.push_str(",");
2078                            results.push(arg);
2079                        }
2080                        self.push_str(") = ");
2081                    }
2082                }
2083                self.push_str("self.func_");
2084                self.push_str(&to_rust_ident(base_name));
2085                self.push_str(".call(store, ");
2086                for operand in operands {
2087                    self.push_str(operand);
2088                    self.push_str(", ");
2089                }
2090                self.push_str(")");
2091                self.push_str("?;\n");
2092                self.after_call = true;
2093                self.caller_memory_available = false; // invalidated by call
2094            }
2095
2096            Instruction::CallInterface { module: _, func } => {
2097                for (i, operand) in operands.iter().enumerate() {
2098                    self.push_str(&format!("let param{} = {};\n", i, operand));
2099                }
2100                if self.gen.opts.tracing && func.params.len() > 0 {
2101                    self.push_str("wit_bindgen_host_wasmer_rust::tracing::event!(\n");
2102                    self.push_str("wit_bindgen_host_wasmer_rust::tracing::Level::TRACE,\n");
2103                    for (i, (name, _ty)) in func.params.iter().enumerate() {
2104                        self.push_str(&format!(
2105                            "{} = wit_bindgen_host_wasmer_rust::tracing::field::debug(&param{}),\n",
2106                            to_rust_ident(name),
2107                            i
2108                        ));
2109                    }
2110                    self.push_str(");\n");
2111                }
2112
2113                let mut call = format!("host.{}(", func.name.to_snake_case());
2114                for i in 0..operands.len() {
2115                    call.push_str(&format!("param{}, ", i));
2116                }
2117                call.push_str(")");
2118
2119                self.push_str("let host = &mut data_mut.data;\n");
2120                self.push_str("let result = ");
2121                results.push("result".to_string());
2122                match self.gen.classify_fn_ret(iface, func) {
2123                    FunctionRet::Normal => self.push_str(&call),
2124                    // Unwrap the result, translating errors to unconditional
2125                    // traps
2126                    FunctionRet::CustomToTrap => {
2127                        self.push_str("match ");
2128                        self.push_str(&call);
2129                        self.push_str("{\n");
2130                        self.push_str("Ok(val) => val,\n");
2131                        self.push_str("Err(e) => return Err(host.error_to_trap(e)),\n");
2132                        self.push_str("}");
2133                    }
2134                    // Keep the `Result` as a `Result`, but convert the error
2135                    // to either the expected destination value or a trap,
2136                    // propagating a trap outwards.
2137                    FunctionRet::CustomToError { err, .. } => {
2138                        self.push_str("match ");
2139                        self.push_str(&call);
2140                        self.push_str("{\n");
2141                        self.push_str("Ok(val) => Ok(val),\n");
2142                        self.push_str(&format!("Err(e) => Err(host.error_to_{}(e)?),\n", err));
2143                        self.push_str("}");
2144                    }
2145                }
2146                self.push_str(";\n");
2147
2148                if self.gen.all_needed_handles.len() > 0 {
2149                    self.push_str("drop(tables);\n");
2150                }
2151
2152                self.after_call = true;
2153
2154                match &func.result {
2155                    Type::Unit => {}
2156                    _ if self.gen.opts.tracing => {
2157                        self.push_str("wit_bindgen_host_wasmer_rust::tracing::event!(\n");
2158                        self.push_str("wit_bindgen_host_wasmer_rust::tracing::Level::TRACE,\n");
2159                        self.push_str(&format!(
2160                            "{} = wit_bindgen_host_wasmer_rust::tracing::field::debug(&{0}),\n",
2161                            results[0],
2162                        ));
2163                        self.push_str(");\n");
2164                    }
2165                    _ => {}
2166                }
2167            }
2168
2169            Instruction::Return { amt, .. } => {
2170                let result = match amt {
2171                    0 => format!("Ok(())\n"),
2172                    1 => format!("Ok({})\n", operands[0]),
2173                    _ => format!("Ok(({}))\n", operands.join(", ")),
2174                };
2175                match self.cleanup.take() {
2176                    Some(cleanup) => {
2177                        self.push_str("let ret = ");
2178                        self.push_str(&result);
2179                        self.push_str(";\n");
2180                        self.push_str(&cleanup);
2181                        self.push_str("ret");
2182                    }
2183                    None => self.push_str(&result),
2184                }
2185            }
2186
2187            Instruction::I32Load { offset } => results.push(self.load(*offset, "i32", operands)),
2188            Instruction::I32Load8U { offset } => {
2189                results.push(format!("i32::from({})", self.load(*offset, "u8", operands)));
2190            }
2191            Instruction::I32Load8S { offset } => {
2192                results.push(format!("i32::from({})", self.load(*offset, "i8", operands)));
2193            }
2194            Instruction::I32Load16U { offset } => {
2195                results.push(format!(
2196                    "i32::from({})",
2197                    self.load(*offset, "u16", operands)
2198                ));
2199            }
2200            Instruction::I32Load16S { offset } => {
2201                results.push(format!(
2202                    "i32::from({})",
2203                    self.load(*offset, "i16", operands)
2204                ));
2205            }
2206            Instruction::I64Load { offset } => results.push(self.load(*offset, "i64", operands)),
2207            Instruction::F32Load { offset } => results.push(self.load(*offset, "f32", operands)),
2208            Instruction::F64Load { offset } => results.push(self.load(*offset, "f64", operands)),
2209
2210            Instruction::I32Store { offset } => self.store(*offset, "as_i32", "", operands),
2211            Instruction::I64Store { offset } => self.store(*offset, "as_i64", "", operands),
2212            Instruction::F32Store { offset } => self.store(*offset, "as_f32", "", operands),
2213            Instruction::F64Store { offset } => self.store(*offset, "as_f64", "", operands),
2214            Instruction::I32Store8 { offset } => self.store(*offset, "as_i32", " as u8", operands),
2215            Instruction::I32Store16 { offset } => {
2216                self.store(*offset, "as_i32", " as u16", operands)
2217            }
2218
2219            Instruction::Malloc {
2220                realloc,
2221                size,
2222                align,
2223            } => {
2224                self.needs_functions
2225                    .insert(realloc.to_string(), NeededFunction::Realloc);
2226                let tmp = self.tmp();
2227                let ptr = format!("ptr{}", tmp);
2228                self.push_str(&format!("let {} = ", ptr));
2229                self.call_intrinsic(realloc, format!("store, 0, 0, {}, {}", align, size));
2230                results.push(ptr);
2231            }
2232
2233            Instruction::Free { .. } => unimplemented!(),
2234        }
2235    }
2236}
2237
2238impl NeededFunction {
2239    fn cvt(&self) -> &'static str {
2240        match self {
2241            NeededFunction::Realloc => "(i32, i32, i32, i32), i32",
2242            NeededFunction::Free => "(i32, i32, i32), ()",
2243        }
2244    }
2245
2246    fn ty(&self) -> String {
2247        format!("wasmer::TypedFunction<{}>", self.cvt())
2248    }
2249}
2250
2251fn sorted_iter<K: Ord, V>(map: &HashMap<K, V>) -> impl Iterator<Item = (&K, &V)> {
2252    let mut list = map.into_iter().collect::<Vec<_>>();
2253    list.sort_by_key(|p| p.0);
2254    list.into_iter()
2255}