Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/wiggle/tests/wasmtime_integration.rs
1692 views
1
use wasmtime::{Engine, Linker, Module, Store, Val};
2
use wiggle::GuestMemory;
3
4
// from_witx invocation says the func is async. This context doesn't support async!
5
wiggle::from_witx!({
6
witx: ["tests/atoms.witx"],
7
async: {
8
atoms::{double_int_return_float}
9
}
10
});
11
12
pub mod integration {
13
// The integration invocation says the func is blocking, so it will still work.
14
wiggle::wasmtime_integration!({
15
target: crate,
16
witx: ["tests/atoms.witx"],
17
block_on: {
18
atoms::{double_int_return_float}
19
}
20
});
21
}
22
23
pub struct Ctx;
24
impl wiggle::GuestErrorType for types::Errno {
25
fn success() -> Self {
26
types::Errno::Ok
27
}
28
}
29
30
#[wiggle::async_trait]
31
impl atoms::Atoms for Ctx {
32
fn int_float_args(
33
&mut self,
34
_: &mut GuestMemory<'_>,
35
an_int: u32,
36
an_float: f32,
37
) -> Result<(), types::Errno> {
38
println!("INT FLOAT ARGS: {an_int} {an_float}");
39
Ok(())
40
}
41
async fn double_int_return_float(
42
&mut self,
43
_: &mut GuestMemory<'_>,
44
an_int: u32,
45
) -> Result<types::AliasToFloat, types::Errno> {
46
Ok((an_int as f32) * 2.0)
47
}
48
}
49
50
#[test]
51
fn test_sync_host_func() {
52
let engine = Engine::default();
53
let mut linker = Linker::new(&engine);
54
integration::add_atoms_to_linker(&mut linker, |cx| cx).unwrap();
55
let mut store = store(&engine);
56
let shim_mod = shim_module(&engine);
57
let shim_inst = linker.instantiate(&mut store, &shim_mod).unwrap();
58
59
let mut results = [Val::I32(0)];
60
shim_inst
61
.get_func(&mut store, "int_float_args_shim")
62
.unwrap()
63
.call(&mut store, &[0i32.into(), 123.45f32.into()], &mut results)
64
.unwrap();
65
66
assert_eq!(
67
results[0].unwrap_i32(),
68
types::Errno::Ok as i32,
69
"int_float_args errno"
70
);
71
}
72
73
#[test]
74
fn test_async_host_func() {
75
let engine = Engine::default();
76
let mut linker = Linker::new(&engine);
77
integration::add_atoms_to_linker(&mut linker, |cx| cx).unwrap();
78
let mut store = store(&engine);
79
80
let shim_mod = shim_module(&engine);
81
let shim_inst = linker.instantiate(&mut store, &shim_mod).unwrap();
82
83
let input: i32 = 123;
84
let result_location: i32 = 0;
85
86
let mut results = [Val::I32(0)];
87
shim_inst
88
.get_func(&mut store, "double_int_return_float_shim")
89
.unwrap()
90
.call(
91
&mut store,
92
&[input.into(), result_location.into()],
93
&mut results,
94
)
95
.unwrap();
96
97
assert_eq!(
98
results[0].unwrap_i32(),
99
types::Errno::Ok as i32,
100
"double_int_return_float errno"
101
);
102
103
// The actual result is in memory:
104
let mem = shim_inst.get_memory(&mut store, "memory").unwrap();
105
let mut result_bytes: [u8; 4] = [0, 0, 0, 0];
106
mem.read(&store, result_location as usize, &mut result_bytes)
107
.unwrap();
108
let result = f32::from_le_bytes(result_bytes);
109
assert_eq!((input * 2) as f32, result);
110
}
111
112
fn store(engine: &Engine) -> Store<Ctx> {
113
Store::new(engine, Ctx)
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