1#[expect(deprecated)]
2use crate::InstancePre;
3use crate::{
4 collections::{
5 string_interner::{InternHint, Sym as Symbol},
6 StringInterner,
7 },
8 func::{FuncEntity, HostFuncEntity, HostFuncTrampolineEntity},
9 module::{ImportName, ImportType},
10 AsContext,
11 AsContextMut,
12 Caller,
13 Engine,
14 Error,
15 Extern,
16 ExternType,
17 Func,
18 FuncType,
19 Instance,
20 IntoFunc,
21 Module,
22 Val,
23};
24use alloc::{
25 collections::{btree_map::Entry, BTreeMap},
26 sync::Arc,
27 vec::Vec,
28};
29use core::{
30 fmt::{self, Debug, Display},
31 marker::PhantomData,
32};
33
34#[derive(Debug)]
36pub enum LinkerError {
37 DuplicateDefinition {
39 import_name: ImportName,
41 },
42 MissingDefinition {
44 name: ImportName,
46 ty: ExternType,
48 },
49 InvalidTypeDefinition {
51 name: ImportName,
53 expected: ExternType,
55 found: ExternType,
57 },
58}
59
60impl LinkerError {
61 fn missing_definition(import: &ImportType) -> Self {
63 Self::MissingDefinition {
64 name: import.import_name().clone(),
65 ty: import.ty().clone(),
66 }
67 }
68
69 fn invalid_type_definition(import: &ImportType, found: &ExternType) -> Self {
71 Self::InvalidTypeDefinition {
72 name: import.import_name().clone(),
73 expected: import.ty().clone(),
74 found: found.clone(),
75 }
76 }
77}
78
79impl core::error::Error for LinkerError {}
80
81impl Display for LinkerError {
82 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
83 match self {
84 Self::DuplicateDefinition { import_name } => {
85 write!(
86 f,
87 "encountered duplicate definition with name `{import_name}`",
88 )
89 }
90 Self::MissingDefinition { name, ty } => {
91 write!(
92 f,
93 "cannot find definition for import {name} with type {ty:?}",
94 )
95 }
96 Self::InvalidTypeDefinition {
97 name,
98 expected,
99 found,
100 } => {
101 write!(f, "found definition for import {name} with type {expected:?} but found type {found:?}")
102 }
103 }
104 }
105}
106
107#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
109#[repr(transparent)]
110struct ImportKey {
111 module_and_name: u64,
115}
116
117impl Debug for ImportKey {
118 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119 f.debug_struct("ImportKey")
120 .field("module", &self.module())
121 .field("name", &self.name())
122 .finish()
123 }
124}
125
126impl ImportKey {
127 #[inline]
129 pub fn new(module: Symbol, name: Symbol) -> Self {
130 let module_and_name = (u64::from(module.into_u32()) << 32) | u64::from(name.into_u32());
131 Self { module_and_name }
132 }
133
134 #[inline]
136 pub fn module(&self) -> Symbol {
137 Symbol::from_u32((self.module_and_name >> 32) as u32)
138 }
139
140 #[inline]
142 pub fn name(&self) -> Symbol {
143 Symbol::from_u32(self.module_and_name as u32)
144 }
145}
146
147#[derive(Debug)]
149enum Definition<T> {
150 Extern(Extern),
152 HostFunc(HostFuncTrampolineEntity<T>),
154}
155
156impl<T> Clone for Definition<T> {
157 fn clone(&self) -> Self {
158 match self {
159 Self::Extern(definition) => Self::Extern(*definition),
160 Self::HostFunc(host_func) => Self::HostFunc(host_func.clone()),
161 }
162 }
163}
164
165impl<T> Definition<T> {
166 fn as_extern(&self) -> Option<&Extern> {
170 match self {
171 Definition::Extern(item) => Some(item),
172 Definition::HostFunc(_) => None,
173 }
174 }
175
176 pub fn ty(&self, ctx: impl AsContext) -> ExternType {
178 match self {
179 Definition::Extern(item) => item.ty(ctx),
180 Definition::HostFunc(host_func) => ExternType::Func(host_func.func_type().clone()),
181 }
182 }
183
184 pub fn as_func(&self, mut ctx: impl AsContextMut<Data = T>) -> Option<Func> {
195 match self {
196 Definition::Extern(Extern::Func(func)) => Some(*func),
197 Definition::HostFunc(host_func) => {
198 let trampoline = ctx
199 .as_context_mut()
200 .store
201 .alloc_trampoline(host_func.trampoline().clone());
202 let ty = host_func.func_type();
203 let entity = HostFuncEntity::new(ctx.as_context().engine(), ty, trampoline);
204 let func = ctx
205 .as_context_mut()
206 .store
207 .inner
208 .alloc_func(FuncEntity::Host(entity));
209 Some(func)
210 }
211 _ => None,
212 }
213 }
214}
215
216#[derive(Debug)]
218pub struct Linker<T> {
219 engine: Engine,
226 shared: Option<Arc<LinkerInner<T>>>,
230 inner: LinkerInner<T>,
232}
233
234impl<T> Clone for Linker<T> {
235 fn clone(&self) -> Linker<T> {
236 Self {
237 engine: self.engine.clone(),
238 shared: self.shared.clone(),
239 inner: self.inner.clone(),
240 }
241 }
242}
243
244impl<T> Default for Linker<T> {
245 fn default() -> Self {
246 Self::new(&Engine::default())
247 }
248}
249
250impl<T> Linker<T> {
251 pub fn new(engine: &Engine) -> Self {
253 Self {
254 engine: engine.clone(),
255 shared: None,
256 inner: LinkerInner::default(),
257 }
258 }
259
260 #[expect(deprecated)]
262 pub fn build() -> LinkerBuilder<state::Constructing, T> {
263 LinkerBuilder {
264 inner: Arc::new(LinkerInner::default()),
265 marker: PhantomData,
266 }
267 }
268
269 pub fn engine(&self) -> &Engine {
271 &self.engine
272 }
273
274 pub fn allow_shadowing(&mut self, allow: bool) -> &mut Self {
278 self.inner.allow_shadowing(allow);
279 self
280 }
281
282 fn ensure_undefined(&self, module: &str, name: &str) -> Result<(), LinkerError> {
290 if let Some(shared) = &self.shared {
291 if shared.has_definition(module, name) {
292 return Err(LinkerError::DuplicateDefinition {
293 import_name: ImportName::new(module, name),
294 });
295 }
296 }
297 Ok(())
298 }
299
300 pub fn define(
306 &mut self,
307 module: &str,
308 name: &str,
309 item: impl Into<Extern>,
310 ) -> Result<&mut Self, LinkerError> {
311 self.ensure_undefined(module, name)?;
312 let key = self.inner.new_import_key(module, name);
313 self.inner.insert(key, Definition::Extern(item.into()))?;
314 Ok(self)
315 }
316
317 pub fn func_new(
325 &mut self,
326 module: &str,
327 name: &str,
328 ty: FuncType,
329 func: impl Fn(Caller<'_, T>, &[Val], &mut [Val]) -> Result<(), Error> + Send + Sync + 'static,
330 ) -> Result<&mut Self, LinkerError> {
331 self.ensure_undefined(module, name)?;
332 let func = HostFuncTrampolineEntity::new(ty, func);
333 let key = self.inner.new_import_key(module, name);
334 self.inner.insert(key, Definition::HostFunc(func))?;
335 Ok(self)
336 }
337
338 pub fn func_wrap<Params, Args>(
360 &mut self,
361 module: &str,
362 name: &str,
363 func: impl IntoFunc<T, Params, Args>,
364 ) -> Result<&mut Self, LinkerError> {
365 self.ensure_undefined(module, name)?;
366 let func = HostFuncTrampolineEntity::wrap(func);
367 let key = self.inner.new_import_key(module, name);
368 self.inner.insert(key, Definition::HostFunc(func))?;
369 Ok(self)
370 }
371
372 pub fn get(
381 &self,
382 context: impl AsContext<Data = T>,
383 module: &str,
384 name: &str,
385 ) -> Option<Extern> {
386 match self.get_definition(context, module, name) {
387 Some(Definition::Extern(item)) => Some(*item),
388 _ => None,
389 }
390 }
391
392 fn get_definition(
400 &self,
401 context: impl AsContext<Data = T>,
402 module: &str,
403 name: &str,
404 ) -> Option<&Definition<T>> {
405 assert!(Engine::same(
406 context.as_context().store.engine(),
407 self.engine()
408 ));
409 if let Some(shared) = &self.shared {
410 if let Some(item) = shared.get_definition(module, name) {
411 return Some(item);
412 }
413 }
414 self.inner.get_definition(module, name)
415 }
416
417 pub fn instance(
433 &mut self,
434 mut store: impl AsContextMut<Data = T>,
435 module_name: &str,
436 instance: Instance,
437 ) -> Result<&mut Self, Error> {
438 assert!(Engine::same(
439 store.as_context().store.engine(),
440 self.engine()
441 ));
442 let mut store = store.as_context_mut();
443 for export in instance.exports(&mut store) {
444 let key = self.inner.new_import_key(module_name, export.name());
445 let def = Definition::Extern(export.into_extern());
446 self.inner.insert(key, def)?;
447 }
448 Ok(self)
449 }
450
451 pub fn alias_module(&mut self, module: &str, as_module: &str) -> Result<(), Error> {
461 self.inner.alias_module(module, as_module)
462 }
463
464 #[deprecated(
475 since = "0.49.0",
476 note = "\
477 use `Linker::instantiate_and_start` instead. \
478 Prevent `start` function execution by enabling fuel metering and setting fuel to zero before instantiation. \
479 "
480 )]
481 #[expect(deprecated)]
482 pub fn instantiate(
483 &self,
484 mut context: impl AsContextMut<Data = T>,
485 module: &Module,
486 ) -> Result<InstancePre, Error> {
487 assert!(Engine::same(self.engine(), context.as_context().engine()));
488 let externals = module
491 .imports()
492 .map(|import| self.process_import(&mut context, import))
493 .collect::<Result<Vec<Extern>, Error>>()?;
494 module.instantiate(context, externals)
495 }
496
497 pub fn instantiate_and_start(
509 &self,
510 mut context: impl AsContextMut<Data = T>,
511 module: &Module,
512 ) -> Result<Instance, Error> {
513 #[expect(deprecated)]
514 self.instantiate(&mut context, module)
515 .and_then(|instance| instance.start(&mut context))
516 }
517
518 fn process_import(
528 &self,
529 mut context: impl AsContextMut<Data = T>,
530 import: ImportType,
531 ) -> Result<Extern, Error> {
532 assert!(Engine::same(self.engine(), context.as_context().engine()));
533 let module_name = import.module();
534 let field_name = import.name();
535 let resolved = self
536 .get_definition(context.as_context(), module_name, field_name)
537 .ok_or_else(|| LinkerError::missing_definition(&import))?;
538 let invalid_type =
539 |context| LinkerError::invalid_type_definition(&import, &resolved.ty(context));
540 match import.ty() {
541 ExternType::Func(_expected) => {
542 let func = resolved
543 .as_func(&mut context)
544 .ok_or_else(|| invalid_type(context))?;
545 Ok(Extern::Func(func))
546 }
547 ExternType::Table(_expected) => {
548 let table = resolved
549 .as_extern()
550 .copied()
551 .and_then(Extern::into_table)
552 .ok_or_else(|| invalid_type(context))?;
553 Ok(Extern::Table(table))
554 }
555 ExternType::Memory(_expected) => {
556 let memory = resolved
557 .as_extern()
558 .copied()
559 .and_then(Extern::into_memory)
560 .ok_or_else(|| invalid_type(context))?;
561 Ok(Extern::Memory(memory))
562 }
563 ExternType::Global(_expected) => {
564 let global = resolved
565 .as_extern()
566 .copied()
567 .and_then(Extern::into_global)
568 .ok_or_else(|| invalid_type(context))?;
569 Ok(Extern::Global(global))
570 }
571 }
572 }
573}
574
575#[deprecated(since = "0.49.0", note = "use `Linker` or `Instance::new` instead")]
577pub mod state {
578 #[deprecated(since = "0.49.0", note = "use `Linker` or `Instance::new` instead")]
582 pub enum Constructing {}
583
584 #[deprecated(since = "0.49.0", note = "use `Linker` or `Instance::new` instead")]
589 pub enum Ready {}
590}
591
592#[derive(Debug)]
596#[deprecated(since = "0.49.0", note = "use `Linker` or `Instance::new` instead")]
597pub struct LinkerBuilder<State, T> {
598 inner: Arc<LinkerInner<T>>,
600 marker: PhantomData<fn() -> State>,
602}
603
604#[expect(deprecated)]
605impl<T> Clone for LinkerBuilder<state::Ready, T> {
606 fn clone(&self) -> Self {
607 Self {
608 inner: self.inner.clone(),
609 marker: PhantomData,
610 }
611 }
612}
613
614#[expect(deprecated)]
615impl<T> LinkerBuilder<state::Ready, T> {
616 pub fn create(&self, engine: &Engine) -> Linker<T> {
618 Linker {
619 engine: engine.clone(),
620 shared: self.inner.clone().into(),
621 inner: <LinkerInner<T>>::default(),
622 }
623 }
624}
625
626#[expect(deprecated)]
627impl<T> LinkerBuilder<state::Constructing, T> {
628 pub fn finish(self) -> LinkerBuilder<state::Ready, T> {
630 LinkerBuilder {
631 inner: self.inner,
632 marker: PhantomData,
633 }
634 }
635
636 fn inner_mut(&mut self) -> &mut LinkerInner<T> {
642 Arc::get_mut(&mut self.inner).unwrap_or_else(|| {
643 unreachable!("tried to define host function in LinkerBuilder after Linker creation")
644 })
645 }
646
647 pub fn func_new(
659 &mut self,
660 module: &str,
661 name: &str,
662 ty: FuncType,
663 func: impl Fn(Caller<'_, T>, &[Val], &mut [Val]) -> Result<(), Error> + Send + Sync + 'static,
664 ) -> Result<&mut Self, LinkerError> {
665 self.inner_mut().func_new(module, name, ty, func)?;
666 Ok(self)
667 }
668
669 pub fn func_wrap<Params, Args>(
695 &mut self,
696 module: &str,
697 name: &str,
698 func: impl IntoFunc<T, Params, Args>,
699 ) -> Result<&mut Self, LinkerError> {
700 self.inner_mut().func_wrap(module, name, func)?;
701 Ok(self)
702 }
703}
704
705#[derive(Debug)]
707pub struct LinkerInner<T> {
708 strings: StringInterner,
710 definitions: BTreeMap<ImportKey, Definition<T>>,
719 allow_shadowing: bool,
721}
722
723impl<T> Default for LinkerInner<T> {
724 fn default() -> Self {
725 Self {
726 strings: StringInterner::default(),
727 definitions: BTreeMap::default(),
728 allow_shadowing: false,
729 }
730 }
731}
732
733impl<T> Clone for LinkerInner<T> {
734 fn clone(&self) -> Self {
735 Self {
736 strings: self.strings.clone(),
737 definitions: self.definitions.clone(),
738 allow_shadowing: self.allow_shadowing,
739 }
740 }
741}
742
743impl<T> LinkerInner<T> {
744 pub fn allow_shadowing(&mut self, allow: bool) {
748 self.allow_shadowing = allow;
749 }
750
751 fn new_import_key(&mut self, module: &str, name: &str) -> ImportKey {
753 ImportKey::new(
754 self.strings
755 .get_or_intern_with_hint(module, InternHint::LikelyExists),
756 self.strings
757 .get_or_intern_with_hint(name, InternHint::LikelyNew),
758 )
759 }
760
761 fn get_import_key(&self, module: &str, name: &str) -> Option<ImportKey> {
763 Some(ImportKey::new(
764 self.strings.get(module)?,
765 self.strings.get(name)?,
766 ))
767 }
768
769 fn resolve_import_key(&self, key: ImportKey) -> Option<(&str, &str)> {
771 let module_name = self.strings.resolve(key.module())?;
772 let item_name = self.strings.resolve(key.name())?;
773 Some((module_name, item_name))
774 }
775
776 fn insert(&mut self, key: ImportKey, item: Definition<T>) -> Result<(), LinkerError> {
782 match self.definitions.entry(key) {
783 Entry::Occupied(mut entry) if self.allow_shadowing => {
784 entry.insert(item);
785 }
786 Entry::Occupied(_) => {
787 let (module_name, field_name) = self
788 .resolve_import_key(key)
789 .unwrap_or_else(|| panic!("encountered missing import names for key {key:?}"));
790 let import_name = ImportName::new(module_name, field_name);
791 return Err(LinkerError::DuplicateDefinition { import_name });
792 }
793 Entry::Vacant(v) => {
794 v.insert(item);
795 }
796 }
797 Ok(())
798 }
799
800 pub fn alias_module(&mut self, module: &str, as_module: &str) -> Result<(), Error> {
804 let module = self
805 .strings
806 .get_or_intern_with_hint(module, InternHint::LikelyExists);
807 let as_module = self
808 .strings
809 .get_or_intern_with_hint(as_module, InternHint::LikelyNew);
810 let items = self
811 .definitions
812 .iter()
813 .filter(|(key, _def)| key.module() == module)
814 .map(|(key, def)| (key.name(), def.clone()))
815 .collect::<Vec<_>>();
816 for (name, item) in items {
817 self.insert(ImportKey::new(as_module, name), item)?;
818 }
819 Ok(())
820 }
821
822 pub fn func_new(
830 &mut self,
831 module: &str,
832 name: &str,
833 ty: FuncType,
834 func: impl Fn(Caller<'_, T>, &[Val], &mut [Val]) -> Result<(), Error> + Send + Sync + 'static,
835 ) -> Result<&mut Self, LinkerError> {
836 let func = HostFuncTrampolineEntity::new(ty, func);
837 let key = self.new_import_key(module, name);
838 self.insert(key, Definition::HostFunc(func))?;
839 Ok(self)
840 }
841
842 pub fn func_wrap<Params, Args>(
864 &mut self,
865 module: &str,
866 name: &str,
867 func: impl IntoFunc<T, Params, Args>,
868 ) -> Result<&mut Self, LinkerError> {
869 let func = HostFuncTrampolineEntity::wrap(func);
870 let key = self.new_import_key(module, name);
871 self.insert(key, Definition::HostFunc(func))?;
872 Ok(self)
873 }
874
875 fn get_definition(&self, module: &str, name: &str) -> Option<&Definition<T>> {
883 let key = self.get_import_key(module, name)?;
884 self.definitions.get(&key)
885 }
886
887 fn has_definition(&self, module: &str, name: &str) -> bool {
889 let Some(key) = self.get_import_key(module, name) else {
890 return false;
891 };
892 self.definitions.contains_key(&key)
893 }
894}
895
896#[cfg(test)]
897mod tests {
898 use super::*;
899 use crate::{Store, ValType};
900
901 struct HostState {
902 a: i32,
903 b: i64,
904 }
905
906 #[test]
907 fn linker_funcs_work() {
908 let engine = Engine::default();
909 let mut linker = <Linker<HostState>>::new(&engine);
910 linker
911 .func_new(
912 "host",
913 "get_a",
914 FuncType::new([], [ValType::I32]),
915 |ctx: Caller<HostState>, _params: &[Val], results: &mut [Val]| {
916 results[0] = Val::from(ctx.data().a);
917 Ok(())
918 },
919 )
920 .unwrap();
921 linker
922 .func_new(
923 "host",
924 "set_a",
925 FuncType::new([ValType::I32], []),
926 |mut ctx: Caller<HostState>, params: &[Val], _results: &mut [Val]| {
927 ctx.data_mut().a = params[0].i32().unwrap();
928 Ok(())
929 },
930 )
931 .unwrap();
932 linker
933 .func_wrap("host", "get_b", |ctx: Caller<HostState>| ctx.data().b)
934 .unwrap();
935 linker
936 .func_wrap("host", "set_b", |mut ctx: Caller<HostState>, value: i64| {
937 ctx.data_mut().b = value
938 })
939 .unwrap();
940 let a_init = 42;
941 let b_init = 77;
942 let mut store = <Store<HostState>>::new(
943 &engine,
944 HostState {
945 a: a_init,
946 b: b_init,
947 },
948 );
949 let wasm = r#"
950 (module
951 (import "host" "get_a" (func $host_get_a (result i32)))
952 (import "host" "set_a" (func $host_set_a (param i32)))
953 (import "host" "get_b" (func $host_get_b (result i64)))
954 (import "host" "set_b" (func $host_set_b (param i64)))
955
956 (func (export "wasm_get_a") (result i32)
957 (call $host_get_a)
958 )
959 (func (export "wasm_set_a") (param $param i32)
960 (call $host_set_a (local.get $param))
961 )
962
963 (func (export "wasm_get_b") (result i64)
964 (call $host_get_b)
965 )
966 (func (export "wasm_set_b") (param $param i64)
967 (call $host_set_b (local.get $param))
968 )
969 )
970 "#;
971 let module = Module::new(&engine, wasm).unwrap();
972 let instance = linker.instantiate_and_start(&mut store, &module).unwrap();
973
974 let wasm_get_a = instance
975 .get_typed_func::<(), i32>(&store, "wasm_get_a")
976 .unwrap();
977 let wasm_set_a = instance
978 .get_typed_func::<i32, ()>(&store, "wasm_set_a")
979 .unwrap();
980 let wasm_get_b = instance
981 .get_typed_func::<(), i64>(&store, "wasm_get_b")
982 .unwrap();
983 let wasm_set_b = instance
984 .get_typed_func::<i64, ()>(&store, "wasm_set_b")
985 .unwrap();
986
987 assert_eq!(wasm_get_a.call(&mut store, ()).unwrap(), a_init);
988 wasm_set_a.call(&mut store, 100).unwrap();
989 assert_eq!(wasm_get_a.call(&mut store, ()).unwrap(), 100);
990
991 assert_eq!(wasm_get_b.call(&mut store, ()).unwrap(), b_init);
992 wasm_set_b.call(&mut store, 200).unwrap();
993 assert_eq!(wasm_get_b.call(&mut store, ()).unwrap(), 200);
994 }
995
996 #[test]
997 fn build_linker() {
998 let mut builder = <Linker<()>>::build();
999 builder
1000 .func_wrap("env", "foo", || std::println!("called foo"))
1001 .unwrap();
1002 builder
1003 .func_new(
1004 "env",
1005 "bar",
1006 FuncType::new([], []),
1007 |_caller, _params, _results| {
1008 std::println!("called bar");
1009 Ok(())
1010 },
1011 )
1012 .unwrap();
1013 let builder = builder.finish();
1014 for _ in 0..3 {
1015 let engine = Engine::default();
1016 let _ = builder.create(&engine);
1017 }
1018 }
1019
1020 #[test]
1021 fn linker_builder_uses() {
1022 use crate::{Engine, Linker, Module, Store};
1023 let wasm = r#"
1024 (module
1025 (import "host" "func.0" (func $host_func.0))
1026 (import "host" "func.1" (func $host_func.1))
1027 (func (export "hello")
1028 (call $host_func.0)
1029 (call $host_func.1)
1030 )
1031 )"#;
1032 let engine = Engine::default();
1033 let mut builder = <Linker<()>>::build();
1034 builder
1035 .func_wrap("host", "func.0", |_caller: Caller<()>| ())
1036 .unwrap();
1037 builder
1038 .func_wrap("host", "func.1", |_caller: Caller<()>| ())
1039 .unwrap();
1040 let linker = builder.finish().create(&engine);
1041 let mut store = Store::new(&engine, ());
1042 let module = Module::new(&engine, wasm).unwrap();
1043 linker.instantiate_and_start(&mut store, &module).unwrap();
1044 }
1045
1046 #[test]
1047 fn linker_builder_and_linker_uses() {
1048 use crate::{Engine, Linker, Module, Store};
1049 let wasm = r#"
1050 (module
1051 (import "host" "func.0" (func $host_func.0))
1052 (import "host" "func.1" (func $host_func.1))
1053 (func (export "hello")
1054 (call $host_func.0)
1055 (call $host_func.1)
1056 )
1057 )"#;
1058 let engine = Engine::default();
1059 let mut builder = <Linker<()>>::build();
1060 builder
1061 .func_wrap("host", "func.0", |_caller: Caller<()>| ())
1062 .unwrap();
1063 let mut linker = builder.finish().create(&engine);
1064 linker
1065 .func_wrap("host", "func.1", |_caller: Caller<()>| ())
1066 .unwrap();
1067 let mut store = Store::new(&engine, ());
1068 let module = Module::new(&engine, wasm).unwrap();
1069 linker.instantiate_and_start(&mut store, &module).unwrap();
1070 }
1071
1072 #[test]
1073 fn linker_builder_no_overwrite() {
1074 use crate::{Engine, Linker};
1075 let engine = Engine::default();
1076 let mut builder = <Linker<()>>::build();
1077 builder
1078 .func_wrap("host", "func.0", |_caller: Caller<()>| ())
1079 .unwrap();
1080 let mut linker = builder.finish().create(&engine);
1081 linker
1082 .func_wrap("host", "func.1", |_caller: Caller<()>| ())
1083 .unwrap();
1084 linker
1086 .func_wrap("host", "func.0", |_caller: Caller<()>| ())
1087 .unwrap_err();
1088 }
1089
1090 #[test]
1091 fn populate_via_imports() {
1092 use crate::{Engine, Func, Linker, Memory, MemoryType, Module, Store};
1093 let wasm = r#"
1094 (module
1095 (import "host" "hello" (func $host_hello (param i32) (result i32)))
1096 (import "env" "memory" (memory $mem 0 4096))
1097 (func (export "hello") (result i32)
1098 (call $host_hello (i32.const 3))
1099 (i32.const 2)
1100 i32.add
1101 )
1102 )"#;
1103 let engine = Engine::default();
1104 let mut linker = <Linker<()>>::new(&engine);
1105 let mut store = Store::new(&engine, ());
1106 let memory = Memory::new(&mut store, MemoryType::new(1, Some(4096))).unwrap();
1107 let module = Module::new(&engine, wasm).unwrap();
1108 linker.define("env", "memory", memory).unwrap();
1109 let func = Func::new(
1110 &mut store,
1111 FuncType::new([ValType::I32], [ValType::I32]),
1112 |_caller, _params, _results| todo!(),
1113 );
1114 linker.define("host", "hello", func).unwrap();
1115 linker.instantiate_and_start(&mut store, &module).unwrap();
1116 }
1117}