Add only_interfaces and with to the bindgen! macro. (#6160)

* Add `only_interfaces` and `with` to the `bindgen!` macro.

* Add a version of the empty_error test for `only_interfaces` and `with`

* Review feedback

* Add docs
This commit is contained in:
Trevor Elliott
2023-04-10 16:28:52 -07:00
committed by GitHub
parent 4053ae9e08
commit 85f0c68008
5 changed files with 257 additions and 8 deletions

View File

@@ -633,3 +633,121 @@ mod variant_error {
Ok(())
}
}
mod with_remapping {
use super::*;
mod interfaces {
wasmtime::component::bindgen!({
inline: "
default world result-playground {
import imports: interface {
empty-error: func(a: float64) -> result<float64>
}
export empty-error: func(a: float64) -> result<float64>
}",
only_interfaces: true,
});
}
wasmtime::component::bindgen!({
inline: "
default world result-playground {
import imports: interface {
empty-error: func(a: float64) -> result<float64>
}
export empty-error: func(a: float64) -> result<float64>
}",
with: {
"imports": interfaces::imports,
},
});
#[test]
fn run() -> Result<(), Error> {
let engine = engine();
let component = Component::new(
&engine,
r#"
(component
(import "imports" (instance $i
(export "empty-error" (func (param "a" float64) (result (result float64))))
))
(core module $libc
(memory (export "memory") 1)
)
(core instance $libc (instantiate $libc))
(core module $m
(import "" "core_empty_error" (func $f (param f64 i32)))
(import "libc" "memory" (memory 0))
(func (export "core_empty_error_export") (param f64) (result i32)
(call $f (local.get 0) (i32.const 8))
(i32.const 8)
)
)
(core func $core_empty_error
(canon lower (func $i "empty-error") (memory $libc "memory"))
)
(core instance $i (instantiate $m
(with "" (instance (export "core_empty_error" (func $core_empty_error))))
(with "libc" (instance $libc))
))
(func $f_empty_error
(export "empty-error")
(param "a" float64)
(result (result float64))
(canon lift (core func $i "core_empty_error_export") (memory $libc "memory"))
)
)
"#,
)?;
#[derive(Default)]
struct MyImports {}
impl interfaces::imports::Host for MyImports {
fn empty_error(&mut self, a: f64) -> Result<Result<f64, ()>, Error> {
if a == 0.0 {
Ok(Ok(a))
} else if a == 1.0 {
Ok(Err(()))
} else {
Err(anyhow!("empty_error: trap"))
}
}
}
let mut linker = Linker::new(&engine);
interfaces::imports::add_to_linker(&mut linker, |f: &mut MyImports| f)?;
let mut store = Store::new(&engine, MyImports::default());
let (results, _) = ResultPlayground::instantiate(&mut store, &component, &linker)?;
assert_eq!(
results
.call_empty_error(&mut store, 0.0)
.expect("no trap")
.expect("no error returned"),
0.0
);
results
.call_empty_error(&mut store, 1.0)
.expect("no trap")
.err()
.expect("() error returned");
let e = results
.call_empty_error(&mut store, 2.0)
.err()
.expect("trap");
assert_eq!(
format!("{}", e.source().expect("trap message is stored in source")),
"empty_error: trap"
);
Ok(())
}
}