1 use anyhow::Result; 2 use wasmtime::component::*; 3 use wasmtime::{Module, Store}; 4 5 #[test] 6 #[cfg_attr(miri, ignore)] 7 fn instance_exports() -> Result<()> { 8 let engine = super::engine(); 9 let component = r#" 10 (component 11 (import "a" (instance $i)) 12 (import "b" (instance $i2 (export "m" (core module)))) 13 14 (alias export $i2 "m" (core module $m)) 15 16 (component $c 17 (component $c 18 (export "m" (core module $m)) 19 ) 20 (instance $c (instantiate $c)) 21 (export "i" (instance $c)) 22 ) 23 (instance $c (instantiate $c)) 24 (export "i" (instance $c)) 25 (export "r" (instance $i)) 26 (export "r2" (instance $i2)) 27 ) 28 "#; 29 let component = Component::new(&engine, component)?; 30 let mut store = Store::new(&engine, ()); 31 let mut linker = Linker::new(&engine); 32 linker.instance("a")?; 33 linker 34 .instance("b")? 35 .module("m", &Module::new(&engine, "(module)")?)?; 36 let instance = linker.instantiate(&mut store, &component)?; 37 38 assert!(instance 39 .get_export(&mut store, None, "not an instance") 40 .is_none()); 41 let i = instance.get_export(&mut store, None, "r").unwrap(); 42 assert!(instance.get_export(&mut store, Some(&i), "x").is_none()); 43 instance.get_export(&mut store, None, "i").unwrap(); 44 let i2 = instance.get_export(&mut store, None, "r2").unwrap(); 45 let m = instance.get_export(&mut store, Some(&i2), "m").unwrap(); 46 assert!(instance.get_func(&mut store, &m).is_none()); 47 assert!(instance.get_module(&mut store, &m).is_some()); 48 49 let i = instance.get_export(&mut store, None, "i").unwrap(); 50 let i = instance.get_export(&mut store, Some(&i), "i").unwrap(); 51 let m = instance.get_export(&mut store, Some(&i), "m").unwrap(); 52 instance.get_module(&mut store, &m).unwrap(); 53 54 Ok(()) 55 } 56 57 #[test] 58 fn export_old_get_new() -> Result<()> { 59 let engine = super::engine(); 60 let component = r#" 61 (component 62 (core module $m) 63 (export "a:b/[email protected]" (core module $m)) 64 65 (instance $i (export "m" (core module $m))) 66 (export "a:b/[email protected]" (instance $i)) 67 ) 68 "#; 69 70 let component = Component::new(&engine, component)?; 71 component.export_index(None, "a:b/[email protected]").unwrap(); 72 let (_, i) = component.export_index(None, "a:b/[email protected]").unwrap(); 73 component.export_index(Some(&i), "m").unwrap(); 74 75 let mut store = Store::new(&engine, ()); 76 let linker = Linker::new(&engine); 77 let instance = linker.instantiate(&mut store, &component)?; 78 79 instance.get_module(&mut store, "a:b/[email protected]").unwrap(); 80 instance 81 .get_export(&mut store, None, "a:b/[email protected]") 82 .unwrap(); 83 84 let i = instance 85 .get_export(&mut store, None, "a:b/[email protected]") 86 .unwrap(); 87 instance.get_export(&mut store, Some(&i), "m").unwrap(); 88 89 Ok(()) 90 } 91 92 #[test] 93 fn export_new_get_old() -> Result<()> { 94 let engine = super::engine(); 95 let component = r#" 96 (component 97 (core module $m) 98 (export "a:b/[email protected]" (core module $m)) 99 100 (instance $i (export "m" (core module $m))) 101 (export "a:b/[email protected]" (instance $i)) 102 ) 103 "#; 104 105 let component = Component::new(&engine, component)?; 106 component.export_index(None, "a:b/[email protected]").unwrap(); 107 let (_, i) = component.export_index(None, "a:b/[email protected]").unwrap(); 108 component.export_index(Some(&i), "m").unwrap(); 109 110 let mut store = Store::new(&engine, ()); 111 let linker = Linker::new(&engine); 112 let instance = linker.instantiate(&mut store, &component)?; 113 114 instance.get_module(&mut store, "a:b/[email protected]").unwrap(); 115 instance 116 .get_export(&mut store, None, "a:b/[email protected]") 117 .unwrap(); 118 119 let i = instance 120 .get_export(&mut store, None, "a:b/[email protected]") 121 .unwrap(); 122 instance.get_export(&mut store, Some(&i), "m").unwrap(); 123 124 Ok(()) 125 } 126 127 #[test] 128 #[cfg_attr(miri, ignore)] 129 fn export_missing_get_max() -> Result<()> { 130 let engine = super::engine(); 131 let component = r#" 132 (component 133 (core module $m1) 134 (core module $m2 (import "" "" (func))) 135 (export "a:b/[email protected]" (core module $m1)) 136 (export "a:b/[email protected]" (core module $m2)) 137 ) 138 "#; 139 140 fn assert_m2(module: &Module) { 141 assert_eq!(module.imports().len(), 1); 142 } 143 fn assert_m1(module: &Module) { 144 assert_eq!(module.imports().len(), 0); 145 } 146 147 let component = Component::new(&engine, component)?; 148 let mut store = Store::new(&engine, ()); 149 let instance = Linker::new(&engine).instantiate(&mut store, &component)?; 150 151 let tests = [ 152 ("a:b/[email protected]", assert_m2 as fn(&_)), // no exact, should pick max available 153 ("a:b/[email protected]", assert_m1), // exact hit 154 ("a:b/[email protected]", assert_m2), // no exact, should pick max available 155 ("a:b/[email protected]", assert_m2), // exact hit 156 ("a:b/[email protected]", assert_m2), // no exact, should pick max available 157 ]; 158 159 for (name, test_fn) in tests { 160 println!("test {name}"); 161 let (_, m) = component.export_index(None, name).unwrap(); 162 let m = instance.get_module(&mut store, &m).unwrap(); 163 test_fn(&m); 164 165 let m = instance.get_module(&mut store, name).unwrap(); 166 test_fn(&m); 167 168 let m = instance.get_export(&mut store, None, name).unwrap(); 169 let m = instance.get_module(&mut store, &m).unwrap(); 170 test_fn(&m); 171 } 172 173 Ok(()) 174 } 175