| 135 | #[wasmtime_test(wasm_features(exceptions))] |
| 136 | #[cfg_attr(miri, ignore)] |
| 137 | fn exception_from_host(config: &mut Config) -> Result<()> { |
| 138 | let engine = Engine::new(config)?; |
| 139 | let mut store = Store::new(&engine, ()); |
| 140 | |
| 141 | let module = Module::new( |
| 142 | &engine, |
| 143 | r#" |
| 144 | (module |
| 145 | (import "test" "e0" (tag $e0 (param i32))) |
| 146 | (import "test" "f" (func $f (param i32))) |
| 147 | |
| 148 | (func $catch (export "catch") (result i32) |
| 149 | (block $b (result i32) |
| 150 | (try_table (result i32) (catch $e0 $b) |
| 151 | i32.const 42 |
| 152 | call $f |
| 153 | i32.const 0)))) |
| 154 | "#, |
| 155 | )?; |
| 156 | |
| 157 | let functy = FuncType::new(&engine, [ValType::I32], []); |
| 158 | let tagty = TagType::new(functy.clone()); |
| 159 | let exnty = ExnType::from_tag_type(&tagty).unwrap(); |
| 160 | let exnpre = ExnRefPre::new(&mut store, exnty); |
| 161 | let tag = Tag::new(&mut store, &tagty)?; |
| 162 | let extfunc = Func::new(&mut store, functy, move |mut caller, args, _rets| { |
| 163 | let exn = ExnRef::new( |
| 164 | &mut caller, |
| 165 | &exnpre, |
| 166 | &tag, |
| 167 | &[Val::I32(args[0].unwrap_i32())], |
| 168 | ) |
| 169 | .unwrap(); |
| 170 | caller.as_context_mut().throw(exn)?; |
| 171 | Ok(()) |
| 172 | }); |
| 173 | let instance = Instance::new( |
| 174 | &mut store, |
| 175 | &module, |
| 176 | &[Extern::Tag(tag), Extern::Func(extfunc)], |
| 177 | )?; |
| 178 | let func = instance.get_func(&mut store, "catch").unwrap(); |
| 179 | let mut results = [Val::null_any_ref()]; |
| 180 | func.call(&mut store, &[], &mut results[..])?; |
| 181 | assert_eq!(results[0].unwrap_i32(), 42); |
| 182 | |
| 183 | Ok(()) |
| 184 | } |
| 185 | |
| 186 | #[wasmtime_test(wasm_features(exceptions))] |
| 187 | fn exception_across_no_wasm(config: &mut Config) -> Result<()> { |