1use crate::metadata::Metadata;
2use std::borrow::Cow;
3use std::collections::{HashMap, HashSet};
4use std::mem;
5use wasm_encoder::{
6 CodeSection, ConstExpr, CustomSection, DataSection, ElementSection, Elements, Encode,
7 EntityType, ExportKind, ExportSection, Function, FunctionSection, GlobalType, ImportSection,
8 MemoryType, Module, NameMap, NameSection, RefType, TableType, TypeSection, ValType,
9};
10use wit_parser::abi::{WasmSignature, WasmType};
11use wit_parser::{
12 Handle, LiftLowerAbi, LiveTypes, ManglingAndAbi, Resolve, ResourceIntrinsic, SizeAlign, Type,
13 TypeDefKind, TypeId, TypeOwner, WasmExport, WasmExportKind, WasmImport, WorldId, WorldItem,
14 WorldKey,
15};
16
17mod async_;
18mod bindgen;
19mod metadata;
20pub use crate::async_::AsyncFilterSet;
21
22pub const C_HEADER: &'static str = include_str!("../wit_dylib.h");
23
24#[derive(Default, Clone, Debug)]
25#[cfg_attr(feature = "clap", derive(clap::Parser))]
26pub struct DylibOpts {
27 #[cfg_attr(feature = "clap", clap(long))]
30 pub interpreter: Option<String>,
31
32 #[cfg_attr(feature = "clap", clap(flatten))]
33 pub async_: AsyncFilterSet,
34}
35
36pub fn create(resolve: &Resolve, world_id: WorldId, mut opts: Option<&mut DylibOpts>) -> Vec<u8> {
37 let mut adapter = Adapter::default();
38 if let Some(opts) = &mut opts {
39 adapter.opts = opts.clone();
40 }
41 let result = adapter.encode(resolve, world_id);
42 if let Some(opts) = &mut opts {
43 **opts = adapter.opts;
44 }
45 result
46}
47
48#[derive(Default)]
49struct Adapter {
50 types: TypeSection,
51 wasm_type_map: HashMap<(Vec<ValType>, Vec<ValType>), u32>,
52 imports: ImportSection,
53 imports_done: bool,
54 global_index: u32,
55 table_base: Option<u32>,
56 memory_base: Option<u32>,
57 stack_pointer: Option<u32>,
58 func_index: u32,
59 functions: FunctionSection,
60 exports: ExportSection,
61 code: CodeSection,
62 global_names: NameMap,
63 function_names: NameMap,
64 metadata: Metadata,
65 type_map: HashMap<TypeId, metadata::Type>,
66 resource_map: HashMap<TypeId, usize>,
67 export_resource_map: HashMap<TypeId, usize>,
68 intrinsics: Option<bindgen::WitInterpreterIntrinsics>,
69 sizes: SizeAlign,
70 opts: DylibOpts,
71
72 elem_segment: Vec<u32>,
78}
79
80#[derive(Default)]
81struct Imports<'a> {
82 wit_imports: Vec<WitImport<'a>>,
83 wit_exports: Vec<WitExport<'a>>,
84}
85
86struct WitImport<'a> {
87 interface: Option<&'a WorldKey>,
88 func: &'a wit_parser::Function,
89 import_index: u32,
90}
91
92struct WitExport<'a> {
93 interface: Option<&'a WorldKey>,
94 func: &'a wit_parser::Function,
95 async_task_return_index: Option<u32>,
96}
97
98impl Adapter {
99 pub fn encode(&mut self, resolve: &Resolve, world_id: WorldId) -> Vec<u8> {
100 self.sizes.fill(resolve);
101
102 let imports = self.add_imports(resolve, world_id);
107 self.imports_done = true;
108
109 let cabi_realloc = self.intrinsics().cabi_realloc;
113 self.exports
114 .export("cabi_realloc", ExportKind::Func, cabi_realloc);
115
116 self.bindgen_world(resolve, world_id, &imports);
119
120 let (metadata_offset, metadata) = self.encode_metadata();
126 let mut ctor = Function::new([]);
127 ctor.instructions().i32_const(metadata_offset as i32);
128 ctor.instructions().global_get(self.memory_base());
129 ctor.instructions().i32_add();
130 ctor.instructions().call(self.intrinsics().initialize);
131 ctor.instructions().end();
132 let ty = self.define_ty([], []);
133 self.define_func("__wasm_call_ctors", ty, ctor, true);
134
135 self.finish(&metadata)
136 }
137
138 fn mangling(
139 &mut self,
140 resolve: &Resolve,
141 interface: Option<&WorldKey>,
142 func: &wit_parser::Function,
143 is_import: bool,
144 ) -> ManglingAndAbi {
145 let abi = if self
146 .opts
147 .async_
148 .is_async(resolve, interface, func, is_import)
149 {
150 LiftLowerAbi::AsyncCallback
151 } else {
152 LiftLowerAbi::Sync
153 };
154 ManglingAndAbi::Legacy(abi)
155 }
156
157 fn resource_intrinsic_mangling(&mut self) -> ManglingAndAbi {
158 ManglingAndAbi::Legacy(LiftLowerAbi::Sync)
159 }
160
161 fn add_imports<'a>(&mut self, resolve: &'a Resolve, world_id: WorldId) -> Imports<'a> {
162 let mut ret = Imports::default();
163 let world = &resolve.worlds[world_id];
164
165 self.intrinsics = Some(bindgen::WitInterpreterIntrinsics::new(self));
168
169 for (interface, import) in world.imports.iter() {
174 match import {
175 WorldItem::Interface { id, .. } => {
176 for (_, func) in resolve.interfaces[*id].functions.iter() {
177 self.add_imported_func(resolve, Some(interface), func, &mut ret);
178 }
179 for (_, ty) in resolve.interfaces[*id].types.iter() {
180 self.add_imported_type_intrinsics(resolve, Some(interface), *ty);
181 }
182 }
183 WorldItem::Type(ty) => {
184 self.add_imported_type_intrinsics(resolve, None, *ty);
185 }
186 WorldItem::Function(func) => {
187 self.add_imported_func(resolve, None, func, &mut ret);
188 }
189 }
190 }
191
192 for (name, export) in world.exports.iter() {
195 match export {
196 WorldItem::Function(func) => {
197 self.add_imported_func_intrinsics_for_export(resolve, None, func, &mut ret);
198 }
199 WorldItem::Interface { id: export, .. } => {
200 for (_, ty) in resolve.interfaces[*export].types.iter() {
201 self.add_imported_type_intrinsics_for_export(resolve, Some(name), *ty);
202 }
203 for (_, func) in resolve.interfaces[*export].functions.iter() {
204 self.add_imported_func_intrinsics_for_export(
205 resolve,
206 Some(name),
207 func,
208 &mut ret,
209 );
210 }
211 }
212 WorldItem::Type(_) => unreachable!(),
213 }
214 }
215
216 let const_i32_global = GlobalType {
217 val_type: ValType::I32,
218 mutable: false,
219 shared: false,
220 };
221 let mut_i32_global = GlobalType {
222 val_type: ValType::I32,
223 mutable: true,
224 shared: false,
225 };
226
227 self.table_base = Some(self.import_global("env", "__table_base", const_i32_global));
228 self.memory_base = Some(self.import_global("env", "__memory_base", const_i32_global));
229 self.stack_pointer = Some(self.import_global("env", "__stack_pointer", mut_i32_global));
230
231 self.imports.import(
232 "env",
233 "memory",
234 EntityType::Memory(MemoryType {
235 minimum: 0,
236 maximum: None,
237 memory64: false,
238 shared: false,
239 page_size_log2: None,
240 }),
241 );
242
243 self.imports.import(
244 "env",
245 "__indirect_function_table",
246 EntityType::Table(TableType {
247 element_type: RefType::FUNCREF,
248 minimum: 0,
249 maximum: None,
250 table64: false,
251 shared: false,
252 }),
253 );
254 ret
255 }
256
257 fn add_imported_func<'a>(
258 &mut self,
259 resolve: &'a Resolve,
260 interface: Option<&'a WorldKey>,
261 func: &'a wit_parser::Function,
262 imports: &mut Imports<'a>,
263 ) {
264 let mangling = self.mangling(resolve, interface, func, true);
265 let (module, name) =
266 resolve.wasm_import_name(mangling, WasmImport::Func { interface, func });
267 let sig = resolve.wasm_signature(mangling.import_variant(), func);
268 let ty = self.define_wasm_sig(sig);
269 let import_index = self.import_func(&module, &name, ty);
270 imports.wit_imports.push(WitImport {
271 func,
272 interface,
273 import_index,
274 });
275 }
276
277 fn add_imported_type_intrinsics<'a>(
278 &mut self,
279 resolve: &Resolve,
280 interface: Option<&'a WorldKey>,
281 id: TypeId,
282 ) {
283 let mangling = self.resource_intrinsic_mangling();
284 let ty = &resolve.types[id];
285 match ty.kind {
286 TypeDefKind::Resource => {
287 let (module, name) = resolve.wasm_import_name(
288 mangling,
289 WasmImport::ResourceIntrinsic {
290 interface,
291 resource: id,
292 intrinsic: ResourceIntrinsic::ImportedDrop,
293 },
294 );
295 let core_ty = self.define_ty([ValType::I32], []);
296 let drop = self.import_func(&module, &name, core_ty);
297 let drop_elem_index = self.push_elem(drop);
298 let resource_index = self.metadata.resources.len();
299 self.metadata.resources.push(metadata::Resource {
300 interface: interface.map(|i| resolve.name_world_key(i)),
301 name: ty.name.clone().unwrap(),
302 drop_elem_index,
303 new_elem_index: None,
304 rep_elem_index: None,
305 });
306 let prev = self.resource_map.insert(id, resource_index);
307 assert!(prev.is_none());
308 }
309
310 _ => {}
313 }
314 }
315
316 fn add_imported_type_intrinsics_for_export<'a>(
317 &mut self,
318 resolve: &Resolve,
319 interface: Option<&'a WorldKey>,
320 id: TypeId,
321 ) {
322 let ty = &resolve.types[id];
323 let mangling = self.resource_intrinsic_mangling();
324 match ty.kind {
325 TypeDefKind::Resource => {
326 let drop_ty = self.define_ty([ValType::I32], []);
327 let new_rep_ty = self.define_ty([ValType::I32], [ValType::I32]);
328
329 let mut import = |ty, intrinsic| {
330 let (module, name) = resolve.wasm_import_name(
331 mangling,
332 WasmImport::ResourceIntrinsic {
333 interface,
334 resource: id,
335 intrinsic,
336 },
337 );
338 self.import_func(&module, &name, ty)
339 };
340
341 let drop = import(drop_ty, ResourceIntrinsic::ExportedDrop);
342 let new = import(new_rep_ty, ResourceIntrinsic::ExportedNew);
343 let rep = import(new_rep_ty, ResourceIntrinsic::ExportedRep);
344
345 let drop_elem_index = self.push_elem(drop);
346 let new_elem_index = Some(self.push_elem(new));
347 let rep_elem_index = Some(self.push_elem(rep));
348
349 let resource_index = self.metadata.resources.len();
350 self.metadata.resources.push(metadata::Resource {
351 interface: interface.map(|i| resolve.name_world_key(i)),
352 name: ty.name.clone().unwrap(),
353 drop_elem_index,
354 new_elem_index,
355 rep_elem_index,
356 });
357
358 let prev = self.export_resource_map.insert(id, resource_index);
364 assert!(prev.is_none());
365 }
366
367 _ => {}
370 }
371 }
372
373 fn add_imported_func_intrinsics_for_export<'a>(
376 &mut self,
377 resolve: &Resolve,
378 interface: Option<&'a WorldKey>,
379 func: &'a wit_parser::Function,
380 ret: &mut Imports<'a>,
381 ) {
382 let mangling = self.mangling(resolve, interface, func, false);
383 let async_task_return_index = if mangling.is_async() {
384 let (module, name, sig) =
385 func.task_return_import(resolve, interface, mangling.mangling());
386 let ty = self.define_wasm_sig(sig);
387 Some(self.import_func(&module, &name, ty))
388 } else {
389 None
390 };
391 ret.wit_exports.push(WitExport {
392 interface,
393 func,
394 async_task_return_index,
395 });
396 }
397
398 fn bindgen_world(&mut self, resolve: &Resolve, world_id: WorldId, imports: &Imports<'_>) {
399 let world = &resolve.worlds[world_id];
400
401 let mut import_types = LiveTypes::default();
405 let mut interface_names = HashMap::new();
406 for (interface, import) in world.imports.iter() {
407 import_types.add_world_item(resolve, import);
408 if let WorldItem::Interface { id, .. } = import {
409 interface_names.insert(*id, interface);
410 }
411 }
412 for (_, export) in world.exports.iter() {
413 match export {
414 WorldItem::Function(func) => import_types.add_func(resolve, func),
415 WorldItem::Interface { .. } => {}
416 WorldItem::Type(_) => unreachable!(),
417 }
418 }
419 for ty in import_types.iter() {
420 let key = match resolve.types[ty].owner {
421 TypeOwner::Interface(id) => Some(interface_names[&id]),
422 _ => None,
423 };
424 self.register_type(resolve, key, ty);
425 }
426
427 for import in imports.wit_imports.iter() {
431 self.bindgen_world_func_import(resolve, import);
432 }
433 for export in imports.wit_exports.iter().filter(|i| i.interface.is_none()) {
434 self.bindgen_world_func_export(resolve, export);
435 }
436
437 let to_keep = imported_types_used_by_exported_interfaces(resolve, world_id);
444 self.type_map.retain(|id, _| to_keep.contains(*id));
445 let mut exported_types = LiveTypes::default();
446 let mut export_names = HashMap::new();
447 for (interface, import) in world.exports.iter() {
448 if let WorldItem::Interface { id, .. } = import {
449 exported_types.add_world_item(resolve, import);
450 export_names.insert(*id, interface);
451 }
452 }
453 for (ty, index) in mem::take(&mut self.export_resource_map) {
454 self.resource_map.insert(ty, index);
455 }
456 for ty in exported_types.iter() {
457 if self.type_map.contains_key(&ty) {
458 continue;
459 }
460 let key = match resolve.types[ty].owner {
461 TypeOwner::Interface(id) => Some(export_names[&id]),
462 _ => None,
463 };
464 self.register_type(resolve, key, ty);
465
466 if let Some(index) = self.resource_map.get(&ty) {
467 self.bindgen_world_export_resource_dtor(resolve, key.unwrap(), ty, *index);
468 }
469 }
470
471 for export in imports.wit_exports.iter().filter(|i| i.interface.is_some()) {
474 self.bindgen_world_func_export(resolve, export);
475 }
476 }
477
478 fn register_type(&mut self, resolve: &Resolve, key: Option<&WorldKey>, id: TypeId) {
484 let ty = &resolve.types[id];
485 let interface = key.map(|key| resolve.name_world_key(key));
486 let name = ty.name.clone();
487 let result = match &ty.kind {
488 TypeDefKind::Record(r) => {
489 let index = self.metadata.records.len();
490 let fields = r
491 .fields
492 .iter()
493 .map(|field| (field.name.clone(), self.lookup_ty(&field.ty)))
494 .collect();
495 self.metadata.records.push(metadata::Record {
496 interface,
497 name: name.unwrap(),
498 fields,
499 });
500 metadata::Type::Record(index)
501 }
502 TypeDefKind::Flags(t) => {
503 let index = self.metadata.flags.len();
504 let names = t.flags.iter().map(|f| f.name.clone()).collect();
505 self.metadata.flags.push(metadata::Flags {
506 interface,
507 name: name.unwrap(),
508 names,
509 });
510 metadata::Type::Flags(index)
511 }
512 TypeDefKind::Tuple(t) => {
513 let index = self.metadata.tuples.len();
514 let types = t.types.iter().map(|t| self.lookup_ty(t)).collect();
515 self.metadata.tuples.push(metadata::Tuple {
516 interface,
517 name,
518 types,
519 });
520 metadata::Type::Tuple(index)
521 }
522 TypeDefKind::Variant(t) => {
523 let index = self.metadata.variants.len();
524 let cases = t
525 .cases
526 .iter()
527 .map(|c| (c.name.clone(), c.ty.map(|t| self.lookup_ty(&t))))
528 .collect();
529 self.metadata.variants.push(metadata::Variant {
530 interface,
531 name: name.unwrap(),
532 cases,
533 });
534 metadata::Type::Variant(index)
535 }
536 TypeDefKind::Enum(t) => {
537 let index = self.metadata.enums.len();
538 let names = t.cases.iter().map(|f| f.name.clone()).collect();
539 self.metadata.enums.push(metadata::Enum {
540 interface,
541 name: name.unwrap(),
542 names,
543 });
544 metadata::Type::Enum(index)
545 }
546 TypeDefKind::Option(t) => {
547 let index = self.metadata.options.len();
548 self.metadata.options.push(metadata::WitOption {
549 interface,
550 name,
551 ty: self.lookup_ty(t),
552 });
553 metadata::Type::Option(index)
554 }
555 TypeDefKind::Result(t) => {
556 let index = self.metadata.results.len();
557 self.metadata.results.push(metadata::WitResult {
558 interface,
559 name,
560 ok: t.ok.map(|t| self.lookup_ty(&t)),
561 err: t.err.map(|t| self.lookup_ty(&t)),
562 });
563 metadata::Type::Result(index)
564 }
565 TypeDefKind::List(t) => {
566 let index = self.metadata.lists.len();
567 self.metadata.lists.push(metadata::List {
568 interface,
569 name,
570 ty: self.lookup_ty(t),
571 });
572 metadata::Type::List(index)
573 }
574 TypeDefKind::FixedSizeList(t, len) => {
575 let index = self.metadata.fixed_size_lists.len();
576 self.metadata
577 .fixed_size_lists
578 .push(metadata::FixedSizeList {
579 interface,
580 name,
581 len: *len,
582 ty: self.lookup_ty(t),
583 });
584 metadata::Type::FixedSizeList(index)
585 }
586 TypeDefKind::Future(t) => {
587 let index = self.metadata.futures.len();
588 self.metadata.futures.push(metadata::Future {
589 interface,
590 name,
591 ty: t.map(|t| self.lookup_ty(&t)),
592 });
593 metadata::Type::Future(index)
594 }
595 TypeDefKind::Stream(t) => {
596 let index = self.metadata.streams.len();
597 self.metadata.streams.push(metadata::Stream {
598 interface,
599 name,
600 ty: t.map(|t| self.lookup_ty(&t)),
601 });
602 metadata::Type::Stream(index)
603 }
604 TypeDefKind::Type(t) => {
605 let index = self.metadata.aliases.len();
606 self.metadata.aliases.push(metadata::Alias {
607 interface,
608 name: name.unwrap(),
609 ty: self.lookup_ty(t),
610 });
611 metadata::Type::Alias(index)
612 }
613 TypeDefKind::Resource => metadata::Type::Own(self.resource_map[&id]),
614
615 TypeDefKind::Handle(Handle::Own(t)) => {
618 metadata::Type::Own(self.resource_map[&dealias(resolve, *t)])
619 }
620 TypeDefKind::Handle(Handle::Borrow(t)) => {
621 metadata::Type::Borrow(self.resource_map[&dealias(resolve, *t)])
622 }
623 TypeDefKind::Unknown => unreachable!(),
624 };
625 self.type_map.insert(id, result);
626 }
627
628 fn lookup_ty(&self, ty: &Type) -> metadata::Type {
629 match ty {
630 Type::U8 => metadata::Type::U8,
631 Type::U16 => metadata::Type::U16,
632 Type::U32 => metadata::Type::U32,
633 Type::U64 => metadata::Type::U64,
634 Type::S8 => metadata::Type::S8,
635 Type::S16 => metadata::Type::S16,
636 Type::S32 => metadata::Type::S32,
637 Type::S64 => metadata::Type::S64,
638 Type::F32 => metadata::Type::F32,
639 Type::F64 => metadata::Type::F64,
640 Type::Bool => metadata::Type::Bool,
641 Type::Char => metadata::Type::Char,
642 Type::String => metadata::Type::String,
643 Type::ErrorContext => metadata::Type::ErrorContext,
644 Type::Id(id) => self.type_map[id],
648 }
649 }
650
651 fn bindgen_world_func_import(&mut self, resolve: &Resolve, import: &WitImport<'_>) {
652 let func = import.func;
653 let mangling = self.mangling(resolve, import.interface, func, true);
654 let body = bindgen::import(
655 self,
656 resolve,
657 func,
658 mangling.import_variant(),
659 import.import_index,
660 );
661
662 let ty = if mangling.is_async() {
663 self.define_ty([ValType::I32; 2], [ValType::I32])
665 } else {
666 self.define_ty([ValType::I32], [])
668 };
669
670 let idx = self.define_func(&format!("adapter {}", func.name), ty, body, false);
671 let elem_index = self.push_elem(idx);
672
673 let sync_import_elem_index;
674 let async_import_elem_index;
675 let async_import_lift_results_elem_index;
676
677 if mangling.is_async() {
678 sync_import_elem_index = None;
679 async_import_elem_index = Some(elem_index);
680 let body =
681 bindgen::lift_async_import_results(self, resolve, func, mangling.import_variant());
682 let ty = self.define_ty([ValType::I32; 2], []);
683 let idx = self.define_func(&format!("lift results {}", func.name), ty, body, false);
684 async_import_lift_results_elem_index = Some(self.push_elem(idx));
685 } else {
686 sync_import_elem_index = Some(elem_index);
687 async_import_elem_index = None;
688 async_import_lift_results_elem_index = None;
689 }
690
691 self.metadata.funcs.push(metadata::Func {
692 interface: import.interface.map(|k| resolve.name_world_key(k)),
693 name: func.name.clone(),
694 sync_import_elem_index,
695 async_import_elem_index,
696 async_import_lift_results_elem_index,
697 async_export_task_return_elem_index: None,
698 args: func
699 .params
700 .iter()
701 .map(|(_, ty)| self.lookup_ty(ty))
702 .collect(),
703 result: func.result.map(|t| self.lookup_ty(&t)),
704 async_abi_area: self.async_import_abi_area(resolve, mangling, func),
705 })
706 }
707
708 fn async_import_abi_area(
711 &self,
712 resolve: &Resolve,
713 mangling: ManglingAndAbi,
714 func: &wit_parser::Function,
715 ) -> Option<(usize, usize)> {
716 if !mangling.is_async() {
717 return None;
718 }
719
720 let info = self
721 .sizes
722 .record(bindgen::async_import_abi_area_types(resolve, func));
723 Some((info.size.size_wasm32(), info.align.align_wasm32()))
724 }
725
726 fn bindgen_world_func_export(&mut self, resolve: &Resolve, export: &WitExport<'_>) {
727 let func = export.func;
728 let mangling = self.mangling(resolve, export.interface, func, false);
729 let sig = resolve.wasm_signature(mangling.export_variant(), func);
730 let ty = self.define_wasm_sig(sig);
731 let name = resolve.wasm_export_name(
732 mangling,
733 WasmExport::Func {
734 interface: export.interface,
735 func,
736 kind: WasmExportKind::Normal,
737 },
738 );
739
740 let metadata_func_index = self.metadata.funcs.len();
741 let body = bindgen::export(
742 self,
743 resolve,
744 func,
745 mangling.export_variant(),
746 metadata_func_index,
747 );
748 self.define_func(&name, ty, body, true);
749
750 let mut async_export_task_return_elem_index = None;
751 match mangling {
752 ManglingAndAbi::Standard32 | ManglingAndAbi::Legacy(LiftLowerAbi::Sync) => {
756 let post_return_name = resolve.wasm_export_name(
757 mangling,
758 WasmExport::Func {
759 interface: export.interface,
760 func,
761 kind: WasmExportKind::PostReturn,
762 },
763 );
764 let post_return = bindgen::post_return(
765 self,
766 resolve,
767 func,
768 mangling.export_variant(),
769 metadata_func_index,
770 );
771 let mut sig = resolve.wasm_signature(mangling.export_variant(), func);
772 sig.params = mem::take(&mut sig.results);
773 let post_return_ty = self.define_wasm_sig(sig);
774 self.define_func(&post_return_name, post_return_ty, post_return, true);
775 }
776
777 ManglingAndAbi::Legacy(LiftLowerAbi::AsyncCallback) => {
784 let callback_name = resolve.wasm_export_name(
785 mangling,
786 WasmExport::Func {
787 interface: export.interface,
788 func,
789 kind: WasmExportKind::Callback,
790 },
791 );
792 let mut callback = Function::new([]);
797 let mut ins = callback.instructions();
798 ins.local_get(0);
799 ins.local_get(1);
800 ins.local_get(2);
801 ins.i32_const(metadata_func_index.try_into().unwrap());
802 let export_async_callback = self.intrinsics().export_async_callback;
803 ins.call(export_async_callback);
804 ins.end();
805 let callback_ty = self.define_ty([ValType::I32; 3], [ValType::I32]);
806 self.define_func(&callback_name, callback_ty, callback, true);
807
808 let task_return = bindgen::task_return(
809 self,
810 resolve,
811 func,
812 mangling.export_variant(),
813 export.async_task_return_index.unwrap(),
814 );
815 let task_return_ty = self.define_ty([ValType::I32], []);
816 let task_return = self.define_func(
817 &format!("task.return {}", func.name),
818 task_return_ty,
819 task_return,
820 false,
821 );
822 async_export_task_return_elem_index = Some(self.push_elem(task_return));
823 }
824
825 ManglingAndAbi::Legacy(LiftLowerAbi::AsyncStackful) => unimplemented!(),
826 }
827
828 self.metadata.funcs.push(metadata::Func {
829 interface: export.interface.map(|k| resolve.name_world_key(k)),
830 name: func.name.clone(),
831 sync_import_elem_index: None,
832 async_import_elem_index: None,
833 async_import_lift_results_elem_index: None,
834 async_export_task_return_elem_index,
835 args: func
836 .params
837 .iter()
838 .map(|(_, ty)| self.lookup_ty(ty))
839 .collect(),
840 result: func.result.map(|t| self.lookup_ty(&t)),
841 async_abi_area: None,
842 })
843 }
844
845 fn bindgen_world_export_resource_dtor(
846 &mut self,
847 resolve: &Resolve,
848 interface: &WorldKey,
849 resource: TypeId,
850 index: usize,
851 ) {
852 let mangling = self.resource_intrinsic_mangling();
853 let name = resolve.wasm_export_name(
854 mangling,
855 WasmExport::ResourceDtor {
856 interface,
857 resource,
858 },
859 );
860 let dtor = self.intrinsics().resource_dtor;
861 let mut func = Function::new([]);
862 let mut ins = func.instructions();
863 ins.i32_const(index.try_into().unwrap());
864 ins.local_get(0);
865 ins.call(dtor);
866 ins.end();
867 let ty = self.define_ty([ValType::I32], []);
868 self.define_func(&name, ty, func, true);
869 }
870
871 fn encode_metadata(&mut self) -> (u32, Vec<u8>) {
872 let (metadata_offset, metadata, apply_relocs) =
873 self.metadata.encode(self.table_base(), self.memory_base());
874 if let Some(apply_relocs) = apply_relocs {
875 let ty = self.define_ty([], []);
876 self.define_func("__wasm_apply_data_relocs", ty, apply_relocs, true);
877 }
878 (metadata_offset, metadata)
879 }
880
881 fn table_base(&self) -> u32 {
882 self.table_base.unwrap()
883 }
884
885 fn intrinsics(&self) -> &bindgen::WitInterpreterIntrinsics {
886 self.intrinsics.as_ref().unwrap()
887 }
888
889 fn stack_pointer(&self) -> u32 {
890 self.stack_pointer.unwrap()
891 }
892
893 fn memory_base(&self) -> u32 {
894 self.memory_base.unwrap()
895 }
896
897 fn push_elem(&mut self, elem: u32) -> u32 {
898 let ret = self.elem_segment.len();
899 self.elem_segment.push(elem);
900 u32::try_from(ret).unwrap()
901 }
902
903 fn finish(&mut self, metadata: &[u8]) -> Vec<u8> {
904 let mut elements = ElementSection::new();
906 if !self.elem_segment.is_empty() {
907 elements.active(
908 Some(0),
909 &ConstExpr::global_get(self.table_base()),
910 Elements::Functions(Cow::Borrowed(&self.elem_segment)),
911 );
912 }
913
914 let mut data = DataSection::new();
916 data.active(
917 0,
918 &ConstExpr::global_get(self.memory_base()),
919 metadata.iter().copied(),
920 );
921
922 let mut names = NameSection::new();
923 names.functions(&self.function_names);
924 names.globals(&self.global_names);
925
926 let dylink0 = {
927 struct MemInfo {
928 memory_size: u32,
929 memory_alignment: u32,
930 table_size: u32,
931 table_alignment: u32,
932 }
933
934 let mem_info = MemInfo {
935 memory_size: metadata.len().try_into().unwrap(),
936 memory_alignment: 2,
937 table_size: self.elem_segment.len().try_into().unwrap(),
938 table_alignment: 0,
939 };
940
941 let mut mem_info_subsection = Vec::new();
942 mem_info.memory_size.encode(&mut mem_info_subsection);
943 mem_info.memory_alignment.encode(&mut mem_info_subsection);
944 mem_info.table_size.encode(&mut mem_info_subsection);
945 mem_info.table_alignment.encode(&mut mem_info_subsection);
946
947 let mut needed_subsection = Vec::new();
948 if let Some(name) = &self.opts.interpreter {
949 [name.as_str()].encode(&mut needed_subsection);
950 }
951
952 const WASM_DYLINK_MEM_INFO: u8 = 1;
953 const WASM_DYLINK_NEEDED: u8 = 2;
954
955 let mut dylink0 = Vec::new();
956 dylink0.push(WASM_DYLINK_MEM_INFO);
957 mem_info_subsection.encode(&mut dylink0);
958 if self.opts.interpreter.is_some() {
959 dylink0.push(WASM_DYLINK_NEEDED);
960 needed_subsection.encode(&mut dylink0);
961 }
962 dylink0
963 };
964
965 let mut result = Module::new();
966 result.section(&CustomSection {
967 name: Cow::Borrowed("dylink.0"),
968 data: Cow::Borrowed(&dylink0),
969 });
970 result.section(&self.types);
971 result.section(&self.imports);
972 result.section(&self.functions);
973 result.section(&self.exports);
974 if !elements.is_empty() {
975 result.section(&elements);
976 }
977 result.section(&self.code);
978 result.section(&data);
979 result.section(&names);
980
981 result.finish()
982 }
983
984 fn define_wasm_sig(&mut self, sig: WasmSignature) -> u32 {
985 let ret = self.define_ty(
986 sig.params
987 .iter()
988 .map(|t| self.map_wasm_type(*t))
989 .collect::<Vec<_>>(),
990 sig.results
991 .iter()
992 .map(|t| self.map_wasm_type(*t))
993 .collect::<Vec<_>>(),
994 );
995 return ret;
996 }
997
998 fn map_wasm_type(&self, a: WasmType) -> ValType {
999 match a {
1000 WasmType::I32 => ValType::I32,
1001 WasmType::I64 => ValType::I64,
1002 WasmType::F32 => ValType::F32,
1003 WasmType::F64 => ValType::F64,
1004 WasmType::PointerOrI64 => ValType::I64,
1005 WasmType::Length | WasmType::Pointer => ValType::I32,
1006 }
1007 }
1008
1009 fn import_global(&mut self, module: &str, name: &str, ty: GlobalType) -> u32 {
1010 assert!(!self.imports_done);
1011 self.imports.import(module, name, ty);
1012 let ret = self.global_index;
1013 self.global_index += 1;
1014 self.global_names.append(ret, name);
1015 ret
1016 }
1017
1018 fn import_func(&mut self, module: &str, name: &str, ty: u32) -> u32 {
1019 assert!(!self.imports_done);
1020 self.imports.import(module, name, EntityType::Function(ty));
1021 let ret = self.func_index;
1022 self.func_index += 1;
1023 self.function_names.append(ret, name);
1024 ret
1025 }
1026
1027 fn define_func(&mut self, name: &str, ty: u32, body: Function, export: bool) -> u32 {
1028 assert!(self.imports_done);
1029 let ret = self.func_index;
1030 self.func_index += 1;
1031 self.functions.function(ty);
1032 self.code.function(&body);
1033 self.function_names.append(ret, name);
1034 if export {
1035 self.exports.export(name, ExportKind::Func, ret);
1036 }
1037 ret
1038 }
1039
1040 fn define_ty<P, R>(&mut self, params: P, results: R) -> u32
1041 where
1042 P: IntoIterator<Item = ValType> + Clone,
1043 P::IntoIter: ExactSizeIterator,
1044 R: IntoIterator<Item = ValType> + Clone,
1045 R::IntoIter: ExactSizeIterator,
1046 {
1047 let param_vec = params.clone().into_iter().collect::<Vec<_>>();
1048 let result_vec = results.clone().into_iter().collect::<Vec<_>>();
1049 *self
1050 .wasm_type_map
1051 .entry((param_vec, result_vec))
1052 .or_insert_with(|| {
1053 let ret = self.types.len();
1054 self.types.ty().function(params, results);
1055 ret
1056 })
1057 }
1058}
1059
1060fn imported_types_used_by_exported_interfaces(resolve: &Resolve, world: WorldId) -> LiveTypes {
1061 let mut live_export_types = LiveTypes::default();
1064 let mut exported_interfaces = HashSet::new();
1065 for (_, export) in resolve.worlds[world].exports.iter() {
1066 match export {
1067 WorldItem::Function(_) => {}
1068 WorldItem::Interface { id, .. } => {
1069 exported_interfaces.insert(*id);
1070 live_export_types.add_interface(resolve, *id)
1071 }
1072 WorldItem::Type(_) => unreachable!(),
1073 }
1074 }
1075
1076 let mut live_import_types = LiveTypes::default();
1080 for ty in live_export_types.iter() {
1081 if let TypeOwner::Interface(id) = resolve.types[ty].owner {
1082 if !exported_interfaces.contains(&id) {
1083 live_import_types.add_interface(resolve, id);
1084 }
1085 }
1086 }
1087
1088 live_import_types
1089}
1090
1091fn dealias(resolve: &Resolve, mut id: TypeId) -> TypeId {
1092 loop {
1093 match resolve.types[id].kind {
1094 TypeDefKind::Type(Type::Id(other)) => id = other,
1095 _ => break id,
1096 }
1097 }
1098}