Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/wiggle/tests/wasmtime_integration.rs
3088 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
impl atoms::Atoms for Ctx {
31
fn int_float_args(
32
&mut self,
33
_: &mut GuestMemory<'_>,
34
an_int: u32,
35
an_float: f32,
36
) -> Result<(), types::Errno> {
37
println!("INT FLOAT ARGS: {an_int} {an_float}");
38
Ok(())
39
}
40
async fn double_int_return_float(
41
&mut self,
42
_: &mut GuestMemory<'_>,
43
an_int: u32,
44
) -> Result<types::AliasToFloat, types::Errno> {
45
Ok((an_int as f32) * 2.0)
46
}
47
}
48
49
#[test]
50
fn test_sync_host_func() {
51
let engine = Engine::default();
52
let mut linker = Linker::new(&engine);
53
integration::add_atoms_to_linker(&mut linker, |cx| cx).unwrap();
54
let mut store = store(&engine);
55
let shim_mod = shim_module(&engine);
56
let shim_inst = linker.instantiate(&mut store, &shim_mod).unwrap();
57
58
let mut results = [Val::I32(0)];
59
shim_inst
60
.get_func(&mut store, "int_float_args_shim")
61
.unwrap()
62
.call(&mut store, &[0i32.into(), 123.45f32.into()], &mut results)
63
.unwrap();
64
65
assert_eq!(
66
results[0].unwrap_i32(),
67
types::Errno::Ok as i32,
68
"int_float_args errno"
69
);
70
}
71
72
#[test]
73
fn test_async_host_func() {
74
let engine = Engine::default();
75
let mut linker = Linker::new(&engine);
76
integration::add_atoms_to_linker(&mut linker, |cx| cx).unwrap();
77
let mut store = store(&engine);
78
79
let shim_mod = shim_module(&engine);
80
let shim_inst = linker.instantiate(&mut store, &shim_mod).unwrap();
81
82
let input: i32 = 123;
83
let result_location: i32 = 0;
84
85
let mut results = [Val::I32(0)];
86
shim_inst
87
.get_func(&mut store, "double_int_return_float_shim")
88
.unwrap()
89
.call(
90
&mut store,
91
&[input.into(), result_location.into()],
92
&mut results,
93
)
94
.unwrap();
95
96
assert_eq!(
97
results[0].unwrap_i32(),
98
types::Errno::Ok as i32,
99
"double_int_return_float errno"
100
);
101
102
// The actual result is in memory:
103
let mem = shim_inst.get_memory(&mut store, "memory").unwrap();
104
let mut result_bytes: [u8; 4] = [0, 0, 0, 0];
105
mem.read(&store, result_location as usize, &mut result_bytes)
106
.unwrap();
107
let result = f32::from_le_bytes(result_bytes);
108
assert_eq!((input * 2) as f32, result);
109
}
110
111
fn store(engine: &Engine) -> Store<Ctx> {
112
Store::new(engine, Ctx)
113
}
114
115
// Wiggle expects the caller to have an exported memory. Wasmtime can only
116
// provide this if the caller is a WebAssembly module, so we need to write
117
// a shim module:
118
fn shim_module(engine: &Engine) -> Module {
119
Module::new(
120
engine,
121
r#"
122
(module
123
(import "atoms" "int_float_args" (func $int_float_args (param i32 f32) (result i32)))
124
(import "atoms" "double_int_return_float" (func $double_int_return_float (param i32 i32) (result i32)))
125
126
(memory 1)
127
(export "memory" (memory 0))
128
129
(func $int_float_args_shim (param i32 f32) (result i32)
130
local.get 0
131
local.get 1
132
call $int_float_args
133
)
134
(func $double_int_return_float_shim (param i32 i32) (result i32)
135
local.get 0
136
local.get 1
137
call $double_int_return_float
138
)
139
(export "int_float_args_shim" (func $int_float_args_shim))
140
(export "double_int_return_float_shim" (func $double_int_return_float_shim))
141
)
142
"#,
143
)
144
.unwrap()
145
}
146
147