Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/wiggle/tests/wasmtime_async.rs
1692 views
1
use wasmtime::{Config, Engine, Linker, Module, Store, Val};
2
use wiggle::GuestMemory;
3
4
wiggle::from_witx!({
5
witx: ["tests/atoms.witx"],
6
async: {
7
atoms::{double_int_return_float}
8
}
9
});
10
11
pub struct Ctx;
12
impl wiggle::GuestErrorType for types::Errno {
13
fn success() -> Self {
14
types::Errno::Ok
15
}
16
}
17
18
#[wiggle::async_trait]
19
impl atoms::Atoms for Ctx {
20
fn int_float_args(
21
&mut self,
22
_: &mut GuestMemory<'_>,
23
an_int: u32,
24
an_float: f32,
25
) -> Result<(), types::Errno> {
26
println!("INT FLOAT ARGS: {an_int} {an_float}");
27
Ok(())
28
}
29
async fn double_int_return_float(
30
&mut self,
31
_: &mut GuestMemory<'_>,
32
an_int: u32,
33
) -> Result<types::AliasToFloat, types::Errno> {
34
// Do something inside this test that is Pending for a trivial amount of time,
35
// to make sure we are hooked up to the tokio executor properly.
36
tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
37
Ok((an_int as f32) * 2.0)
38
}
39
}
40
41
#[tokio::test]
42
async fn test_sync_host_func() {
43
let mut store = async_store();
44
let mut linker = Linker::<Ctx>::new(store.engine());
45
atoms::add_to_linker(&mut linker, |cx| cx).unwrap();
46
let shim_mod = shim_module(linker.engine());
47
let shim_inst = linker
48
.instantiate_async(&mut store, &shim_mod)
49
.await
50
.unwrap();
51
52
let mut results = [Val::I32(0)];
53
shim_inst
54
.get_func(&mut store, "int_float_args_shim")
55
.unwrap()
56
.call_async(&mut store, &[0i32.into(), 123.45f32.into()], &mut results)
57
.await
58
.unwrap();
59
60
assert_eq!(
61
results[0].unwrap_i32(),
62
types::Errno::Ok as i32,
63
"int_float_args errno"
64
);
65
}
66
67
#[tokio::test]
68
async fn test_async_host_func() {
69
let mut store = async_store();
70
let mut linker = Linker::<Ctx>::new(store.engine());
71
atoms::add_to_linker(&mut linker, |cx| cx).unwrap();
72
73
let shim_mod = shim_module(linker.engine());
74
let shim_inst = linker
75
.instantiate_async(&mut store, &shim_mod)
76
.await
77
.unwrap();
78
79
let input: i32 = 123;
80
let result_location: i32 = 0;
81
82
let mut results = [Val::I32(0)];
83
shim_inst
84
.get_func(&mut store, "double_int_return_float_shim")
85
.unwrap()
86
.call_async(
87
&mut store,
88
&[input.into(), result_location.into()],
89
&mut results,
90
)
91
.await
92
.unwrap();
93
94
assert_eq!(
95
results[0].unwrap_i32(),
96
types::Errno::Ok as i32,
97
"double_int_return_float errno"
98
);
99
100
// The actual result is in memory:
101
let mem = shim_inst.get_memory(&mut store, "memory").unwrap();
102
let mut result_bytes: [u8; 4] = [0, 0, 0, 0];
103
mem.read(&store, result_location as usize, &mut result_bytes)
104
.unwrap();
105
let result = f32::from_le_bytes(result_bytes);
106
assert_eq!((input * 2) as f32, result);
107
}
108
109
fn async_store() -> Store<Ctx> {
110
Store::new(
111
&Engine::new(Config::new().async_support(true)).unwrap(),
112
Ctx,
113
)
114
}
115
116
// Wiggle expects the caller to have an exported memory. Wasmtime can only
117
// provide this if the caller is a WebAssembly module, so we need to write
118
// a shim module:
119
fn shim_module(engine: &Engine) -> Module {
120
Module::new(
121
engine,
122
r#"
123
(module
124
(import "atoms" "int_float_args" (func $int_float_args (param i32 f32) (result i32)))
125
(import "atoms" "double_int_return_float" (func $double_int_return_float (param i32 i32) (result i32)))
126
127
(memory 1)
128
(export "memory" (memory 0))
129
130
(func $int_float_args_shim (param i32 f32) (result i32)
131
local.get 0
132
local.get 1
133
call $int_float_args
134
)
135
(func $double_int_return_float_shim (param i32 i32) (result i32)
136
local.get 0
137
local.get 1
138
call $double_int_return_float
139
)
140
(export "int_float_args_shim" (func $int_float_args_shim))
141
(export "double_int_return_float_shim" (func $double_int_return_float_shim))
142
)
143
"#,
144
)
145
.unwrap()
146
}
147
148