use wasmtime::Result; use wasmtime::component::types::ComponentItem; use wasmtime::component::{Component, Linker, ResourceType}; use wasmtime::{Engine, Store}; #[test] fn old_import_importing_new_item() -> Result<()> { let engine = Engine::default(); let mut linker = Linker::<()>::new(&engine); let ty = ResourceType::host::(); linker.root().resource("a:b/c@1.0.1", ty, |_, _| Ok(()))?; let component = Component::new( &engine, r#"(component (import "a:b/c@1.0.0" (type $t (sub resource))) (export "a" (type $t)) )"#, )?; let mut store = Store::new(&engine, ()); let i = linker.instantiate(&mut store, &component)?; assert_eq!(i.get_resource(&mut store, "a"), Some(ty)); Ok(()) } #[test] fn new_import_importing_old_item() -> Result<()> { let engine = Engine::default(); let mut linker = Linker::<()>::new(&engine); let ty = ResourceType::host::(); linker.root().resource("a:b/c@1.0.0", ty, |_, _| Ok(()))?; let component = Component::new( &engine, r#"(component (import "a:b/c@1.0.1" (type $t (sub resource))) (export "a" (type $t)) )"#, )?; let mut store = Store::new(&engine, ()); let i = linker.instantiate(&mut store, &component)?; assert_eq!(i.get_resource(&mut store, "a"), Some(ty)); Ok(()) } #[test] fn import_both_old_and_new() -> Result<()> { let engine = Engine::default(); let mut linker = Linker::<()>::new(&engine); let t1 = ResourceType::host::(); let t2 = ResourceType::host::(); linker.root().resource("a:b/c@1.0.0", t1, |_, _| Ok(()))?; linker.root().resource("a:b/c@1.0.1", t2, |_, _| Ok(()))?; let component = Component::new( &engine, r#"(component (import "a:b/c@1.0.0" (type $t1 (sub resource))) (import "a:b/c@1.0.1" (type $t2 (sub resource))) (export "t1" (type $t1)) (export "t2" (type $t2)) )"#, )?; let mut store = Store::new(&engine, ()); let i = linker.instantiate(&mut store, &component)?; assert_eq!(i.get_resource(&mut store, "t1"), Some(t1)); assert_eq!(i.get_resource(&mut store, "t2"), Some(t2)); Ok(()) } #[test] fn missing_import_selects_max() -> Result<()> { let engine = Engine::default(); let mut linker = Linker::<()>::new(&engine); let t1 = ResourceType::host::(); let t2 = ResourceType::host::(); linker.root().resource("a:b/c@1.0.1", t1, |_, _| Ok(()))?; linker.root().resource("a:b/c@1.0.2", t2, |_, _| Ok(()))?; let component = Component::new( &engine, r#"(component (import "a:b/c@1.0.0" (type $t1 (sub resource))) (import "a:b/c@1.0.3" (type $t2 (sub resource))) (export "t1" (type $t1)) (export "t2" (type $t2)) )"#, )?; let mut store = Store::new(&engine, ()); let i = linker.instantiate(&mut store, &component)?; assert_eq!(i.get_resource(&mut store, "t1"), Some(t2)); assert_eq!(i.get_resource(&mut store, "t2"), Some(t2)); Ok(()) } #[test] #[cfg_attr(miri, ignore)] fn linker_substituting_types_issue_8003() -> Result<()> { let engine = Engine::default(); let linker = Linker::<()>::new(&engine); let component = Component::new( &engine, r#" (component (component $foo (type $_myres (resource (rep i32))) (export $myres "myres" (type $_myres)) (core module $m (func (export "make") (result i32) unreachable) ) (core instance $m (instantiate $m)) (func (export "make") (result (own $myres)) (canon lift (core func $m "make"))) ) (instance $foo (instantiate $foo)) (export "foo" (instance $foo)) ) "#, )?; let component_ty = linker.substituted_component_type(&component)?; let exports = component_ty.exports(&engine); for (_name, item) in exports { match item { ComponentItem::ComponentInstance(instance) => { for _ in instance.exports(&engine) { // .. } } _ => {} } } Ok(()) } #[test] fn linker_defines_unknown_imports_as_traps() -> Result<()> { let engine = Engine::default(); let mut linker = Linker::<()>::new(&engine); let component = Component::new( &engine, r#"(component (import "foo" (func)) (import "bar" (instance (export "baz" (func)))) (import "qux" (type (sub resource))) )"#, )?; linker.define_unknown_imports_as_traps(&component)?; let mut store = Store::new(&engine, ()); let _ = linker.instantiate(&mut store, &component)?; Ok(()) } #[test] fn linker_fails_to_define_unknown_core_module_imports_as_traps() -> Result<()> { let engine = Engine::default(); let mut linker = Linker::<()>::new(&engine); let component = Component::new( &engine, r#"(component (import "foo" (core module)) )"#, )?; assert!(linker.define_unknown_imports_as_traps(&component).is_err()); Ok(()) }