1 use anyhow::Result; 2 use wasmtime::*; 3 4 #[test] 5 fn checks_incompatible_target() -> Result<()> { 6 let mut target = target_lexicon::Triple::host(); 7 target.operating_system = target_lexicon::OperatingSystem::Unknown; 8 match Module::new( 9 &Engine::new(Config::new().target(&target.to_string())?)?, 10 "(module)", 11 ) { 12 Ok(_) => unreachable!(), 13 Err(e) => assert!( 14 format!("{:?}", e).contains("configuration does not match the host"), 15 "bad error: {:?}", 16 e 17 ), 18 } 19 20 Ok(()) 21 } 22 23 #[test] 24 fn caches_across_engines() { 25 let c = Config::new(); 26 27 let bytes = Module::new(&Engine::new(&c).unwrap(), "(module)") 28 .unwrap() 29 .serialize() 30 .unwrap(); 31 32 unsafe { 33 let res = Module::deserialize(&Engine::default(), &bytes); 34 assert!(res.is_ok()); 35 36 // differ in runtime settings 37 let res = Module::deserialize( 38 &Engine::new(Config::new().static_memory_maximum_size(0)).unwrap(), 39 &bytes, 40 ); 41 assert!(res.is_err()); 42 43 // differ in wasm features enabled (which can affect 44 // runtime/compilation settings) 45 let res = Module::deserialize( 46 &Engine::new(Config::new().wasm_simd(false)).unwrap(), 47 &bytes, 48 ); 49 assert!(res.is_err()); 50 } 51 } 52 53 #[test] 54 fn aot_compiles() -> Result<()> { 55 let engine = Engine::default(); 56 let bytes = engine.precompile_module( 57 "(module (func (export \"f\") (param i32) (result i32) local.get 0))".as_bytes(), 58 )?; 59 60 let module = unsafe { Module::deserialize(&engine, &bytes)? }; 61 62 let mut store = Store::new(&engine, ()); 63 let instance = Instance::new(&mut store, &module, &[])?; 64 65 let f = instance.get_typed_func::<i32, i32, _>(&mut store, "f")?; 66 assert_eq!(f.call(&mut store, 101)?, 101); 67 68 Ok(()) 69 } 70 71 #[test] 72 fn serialize_deterministic() { 73 let engine = Engine::default(); 74 75 let assert_deterministic = |wasm: &str| { 76 let p1 = engine.precompile_module(wasm.as_bytes()).unwrap(); 77 let p2 = engine.precompile_module(wasm.as_bytes()).unwrap(); 78 if p1 != p2 { 79 panic!("precompile_module not determinisitc for:\n{}", wasm); 80 } 81 82 let module1 = Module::new(&engine, wasm).unwrap(); 83 let a1 = module1.serialize().unwrap(); 84 let a2 = module1.serialize().unwrap(); 85 if a1 != a2 { 86 panic!("Module::serialize not determinisitc for:\n{}", wasm); 87 } 88 89 let module2 = Module::new(&engine, wasm).unwrap(); 90 let b1 = module2.serialize().unwrap(); 91 let b2 = module2.serialize().unwrap(); 92 if b1 != b2 { 93 panic!("Module::serialize not determinisitc for:\n{}", wasm); 94 } 95 96 if a1 != b2 { 97 panic!("not matching across modules:\n{}", wasm); 98 } 99 if b1 != p2 { 100 panic!("not matching across engine/module:\n{}", wasm); 101 } 102 }; 103 104 assert_deterministic("(module)"); 105 assert_deterministic("(module (func))"); 106 assert_deterministic("(module (func nop))"); 107 assert_deterministic("(module (func) (func (param i32)))"); 108 assert_deterministic("(module (func (export \"f\")) (func (export \"y\")))"); 109 assert_deterministic("(module (func $f) (func $g))"); 110 assert_deterministic("(module (data \"\") (data \"\"))"); 111 assert_deterministic("(module (elem) (elem))"); 112 } 113 114 // This test asserts that the optimization to transform separate data segments 115 // into an initialization image doesn't unnecessarily create a massive module by 116 // accident with a very large initialization image in it. 117 #[test] 118 fn serialize_not_overly_massive() -> Result<()> { 119 let mut config = Config::new(); 120 config.memory_guaranteed_dense_image_size(1 << 20); 121 let engine = Engine::new(&config)?; 122 123 let assert_smaller_than_1mb = |module: &str| -> Result<()> { 124 println!("{}", module); 125 let bytes = Module::new(&engine, module)?.serialize()?; 126 assert!(bytes.len() < (1 << 20)); 127 Ok(()) 128 }; 129 130 // Tons of space between data segments should use sparse initialization, 131 // along with various permutations of empty and nonempty segments. 132 assert_smaller_than_1mb( 133 r#"(module 134 (memory 20000) 135 (data (i32.const 0) "a") 136 (data (i32.const 0x200000) "b") 137 )"#, 138 )?; 139 assert_smaller_than_1mb( 140 r#"(module 141 (memory 20000) 142 (data (i32.const 0) "a") 143 (data (i32.const 0x200000) "") 144 )"#, 145 )?; 146 assert_smaller_than_1mb( 147 r#"(module 148 (memory 20000) 149 (data (i32.const 0) "") 150 (data (i32.const 0x200000) "b") 151 )"#, 152 )?; 153 assert_smaller_than_1mb( 154 r#"(module 155 (memory 20000) 156 (data (i32.const 0) "") 157 (data (i32.const 0x200000) "") 158 )"#, 159 )?; 160 161 // lone data segment 162 assert_smaller_than_1mb( 163 r#"(module 164 (memory 20000) 165 (data (i32.const 0x200000) "b") 166 )"#, 167 )?; 168 169 Ok(()) 170 } 171