1 use anyhow::Result; 2 use wasmtime::component::types::ComponentItem; 3 use wasmtime::component::{Component, Linker, ResourceType}; 4 use wasmtime::{Engine, Store}; 5 6 #[test] 7 fn old_import_importing_new_item() -> Result<()> { 8 let engine = Engine::default(); 9 let mut linker = Linker::<()>::new(&engine); 10 11 let ty = ResourceType::host::<u32>(); 12 linker.root().resource("a:b/[email protected]", ty, |_, _| Ok(()))?; 13 14 let component = Component::new( 15 &engine, 16 r#"(component 17 (import "a:b/[email protected]" (type $t (sub resource))) 18 (export "a" (type $t)) 19 )"#, 20 )?; 21 let mut store = Store::new(&engine, ()); 22 let i = linker.instantiate(&mut store, &component)?; 23 24 assert_eq!(i.get_resource(&mut store, "a"), Some(ty)); 25 26 Ok(()) 27 } 28 29 #[test] 30 fn new_import_importing_old_item() -> Result<()> { 31 let engine = Engine::default(); 32 let mut linker = Linker::<()>::new(&engine); 33 34 let ty = ResourceType::host::<u32>(); 35 linker.root().resource("a:b/[email protected]", ty, |_, _| Ok(()))?; 36 37 let component = Component::new( 38 &engine, 39 r#"(component 40 (import "a:b/[email protected]" (type $t (sub resource))) 41 (export "a" (type $t)) 42 )"#, 43 )?; 44 let mut store = Store::new(&engine, ()); 45 let i = linker.instantiate(&mut store, &component)?; 46 47 assert_eq!(i.get_resource(&mut store, "a"), Some(ty)); 48 49 Ok(()) 50 } 51 52 #[test] 53 fn import_both_old_and_new() -> Result<()> { 54 let engine = Engine::default(); 55 let mut linker = Linker::<()>::new(&engine); 56 57 let t1 = ResourceType::host::<u32>(); 58 let t2 = ResourceType::host::<i32>(); 59 linker.root().resource("a:b/[email protected]", t1, |_, _| Ok(()))?; 60 linker.root().resource("a:b/[email protected]", t2, |_, _| Ok(()))?; 61 62 let component = Component::new( 63 &engine, 64 r#"(component 65 (import "a:b/[email protected]" (type $t1 (sub resource))) 66 (import "a:b/[email protected]" (type $t2 (sub resource))) 67 (export "t1" (type $t1)) 68 (export "t2" (type $t2)) 69 )"#, 70 )?; 71 let mut store = Store::new(&engine, ()); 72 let i = linker.instantiate(&mut store, &component)?; 73 74 assert_eq!(i.get_resource(&mut store, "t1"), Some(t1)); 75 assert_eq!(i.get_resource(&mut store, "t2"), Some(t2)); 76 77 Ok(()) 78 } 79 80 #[test] 81 fn missing_import_selects_max() -> Result<()> { 82 let engine = Engine::default(); 83 let mut linker = Linker::<()>::new(&engine); 84 85 let t1 = ResourceType::host::<u32>(); 86 let t2 = ResourceType::host::<i32>(); 87 linker.root().resource("a:b/[email protected]", t1, |_, _| Ok(()))?; 88 linker.root().resource("a:b/[email protected]", t2, |_, _| Ok(()))?; 89 90 let component = Component::new( 91 &engine, 92 r#"(component 93 (import "a:b/[email protected]" (type $t1 (sub resource))) 94 (import "a:b/[email protected]" (type $t2 (sub resource))) 95 (export "t1" (type $t1)) 96 (export "t2" (type $t2)) 97 )"#, 98 )?; 99 let mut store = Store::new(&engine, ()); 100 let i = linker.instantiate(&mut store, &component)?; 101 102 assert_eq!(i.get_resource(&mut store, "t1"), Some(t2)); 103 assert_eq!(i.get_resource(&mut store, "t2"), Some(t2)); 104 105 Ok(()) 106 } 107 108 #[test] 109 #[cfg_attr(miri, ignore)] 110 fn linker_substituting_types_issue_8003() -> Result<()> { 111 let engine = Engine::default(); 112 let linker = Linker::<()>::new(&engine); 113 let component = Component::new( 114 &engine, 115 r#" 116 (component 117 (component $foo 118 (type $_myres (resource (rep i32))) 119 (export $myres "myres" (type $_myres)) 120 121 (core module $m 122 (func (export "make") (result i32) unreachable) 123 ) 124 (core instance $m (instantiate $m)) 125 126 (func (export "make") (result (own $myres)) 127 (canon lift (core func $m "make"))) 128 ) 129 (instance $foo (instantiate $foo)) 130 (export "foo" (instance $foo)) 131 ) 132 "#, 133 )?; 134 135 let component_ty = linker.substituted_component_type(&component)?; 136 let exports = component_ty.exports(&engine); 137 for (_name, item) in exports { 138 match item { 139 ComponentItem::ComponentInstance(instance) => { 140 for _ in instance.exports(&engine) { 141 // .. 142 } 143 } 144 _ => {} 145 } 146 } 147 Ok(()) 148 } 149 150 #[test] 151 fn linker_defines_unknown_imports_as_traps() -> Result<()> { 152 let engine = Engine::default(); 153 let mut linker = Linker::<()>::new(&engine); 154 155 let component = Component::new( 156 &engine, 157 r#"(component 158 (import "foo" (func)) 159 (import "bar" (instance (export "baz" (func)))) 160 (import "qux" (type (sub resource))) 161 )"#, 162 )?; 163 linker.define_unknown_imports_as_traps(&component)?; 164 let mut store = Store::new(&engine, ()); 165 let _ = linker.instantiate(&mut store, &component)?; 166 167 Ok(()) 168 } 169 170 #[test] 171 fn linker_fails_to_define_unknown_core_module_imports_as_traps() -> Result<()> { 172 let engine = Engine::default(); 173 let mut linker = Linker::<()>::new(&engine); 174 175 let component = Component::new( 176 &engine, 177 r#"(component 178 (import "foo" (core module)) 179 )"#, 180 )?; 181 assert!(linker.define_unknown_imports_as_traps(&component).is_err()); 182 183 Ok(()) 184 } 185