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 #[cfg_attr(feature = "structopt", structopt(long))]
62 pub rustfmt: bool,
63
64 #[cfg_attr(feature = "structopt", structopt(long))]
66 pub tracing: bool,
67
68 #[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 Normal,
85 CustomToTrap,
89 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 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 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 TypeMode::LeafBorrowed("'a")
180 } else {
181 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 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 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 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 self.in_import {
443 return;
444 }
445
446 self.exported_resources.insert(ty);
447
448 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 fn export(&mut self, iface: &Interface, func: &Function) {
480 let prev = mem::take(&mut self.src);
481
482 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 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 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 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 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 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 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 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 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 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 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 tmp: usize,
1287
1288 src: Source,
1290
1291 params: Vec<String>,
1293
1294 block_storage: Vec<Source>,
1296 blocks: Vec<String>,
1297
1298 after_call: bool,
1301 caller_memory_available: bool,
1304 cleanup: Option<String>,
1307
1308 closures: Source,
1311
1312 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 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; }
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 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 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 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 let tmp = self.tmp();
1841 let val = format!("vec{}", tmp);
1842 self.push_str(&format!("let {} = {};\n", val, operands[0]));
1843
1844 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 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 let realloc = realloc.unwrap();
1902 self.needs_functions
1903 .insert(realloc.to_string(), NeededFunction::Realloc);
1904
1905 let tmp = self.tmp();
1907 let val = format!("vec{}", tmp);
1908 self.push_str(&format!("let {} = {};\n", val, operands[0]));
1909
1910 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 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 self.push_str(&format!("let {} = {};\n", vec, operands[0]));
1982 self.push_str(&format!("let {} = {}.len() as i32;\n", len, vec));
1983
1984 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 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; 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; }
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(¶m{}),\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 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 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}