Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/test-programs/src/bin/async_synchronous_transmit.rs
3069 views
1
mod bindings {
2
wit_bindgen::generate!({
3
path: "../misc/component-async-tests/wit",
4
world: "synchronous-transmit-guest",
5
});
6
}
7
8
use {
9
std::mem,
10
test_programs::async_::{
11
CALLBACK_CODE_EXIT, CALLBACK_CODE_YIELD, COMPLETED, DROPPED, EVENT_NONE, context_get,
12
context_set,
13
},
14
};
15
16
#[cfg(target_arch = "wasm32")]
17
#[link(wasm_import_module = "[export]local:local/synchronous-transmit")]
18
unsafe extern "C" {
19
#[link_name = "[task-return]start"]
20
fn task_return_start(_: u32, _: *const u8, _: usize, _: u32, _: u8);
21
}
22
#[cfg(not(target_arch = "wasm32"))]
23
unsafe extern "C" fn task_return_start(_: u32, _: *const u8, _: usize, _: u32, _: u8) {
24
unreachable!()
25
}
26
27
#[cfg(target_arch = "wasm32")]
28
#[link(wasm_import_module = "[export]local:local/synchronous-transmit")]
29
unsafe extern "C" {
30
#[link_name = "[stream-new-0]start"]
31
fn stream_new() -> u64;
32
}
33
#[cfg(not(target_arch = "wasm32"))]
34
unsafe extern "C" fn stream_new() -> u64 {
35
unreachable!()
36
}
37
38
#[cfg(target_arch = "wasm32")]
39
#[link(wasm_import_module = "[export]local:local/synchronous-transmit")]
40
unsafe extern "C" {
41
#[link_name = "[stream-write-0]start"]
42
fn stream_write(_: u32, _: *const u8, _: usize) -> u32;
43
}
44
#[cfg(not(target_arch = "wasm32"))]
45
unsafe extern "C" fn stream_write(_: u32, _: *const u8, _: usize) -> u32 {
46
unreachable!()
47
}
48
49
#[cfg(target_arch = "wasm32")]
50
#[link(wasm_import_module = "[export]local:local/synchronous-transmit")]
51
unsafe extern "C" {
52
#[link_name = "[stream-read-0]start"]
53
fn stream_read(_: u32, _: *mut u8, _: usize) -> u32;
54
}
55
#[cfg(not(target_arch = "wasm32"))]
56
unsafe extern "C" fn stream_read(_: u32, _: *mut u8, _: usize) -> u32 {
57
unreachable!()
58
}
59
60
#[cfg(target_arch = "wasm32")]
61
#[link(wasm_import_module = "[export]local:local/synchronous-transmit")]
62
unsafe extern "C" {
63
#[link_name = "[stream-drop-readable-0]start"]
64
fn stream_drop_readable(_: u32);
65
}
66
#[cfg(not(target_arch = "wasm32"))]
67
unsafe extern "C" fn stream_drop_readable(_: u32) {
68
unreachable!()
69
}
70
71
#[cfg(target_arch = "wasm32")]
72
#[link(wasm_import_module = "[export]local:local/synchronous-transmit")]
73
unsafe extern "C" {
74
#[link_name = "[stream-drop-writable-0]start"]
75
fn stream_drop_writable(_: u32);
76
}
77
#[cfg(not(target_arch = "wasm32"))]
78
unsafe extern "C" fn stream_drop_writable(_: u32) {
79
unreachable!()
80
}
81
82
#[cfg(target_arch = "wasm32")]
83
#[link(wasm_import_module = "[export]local:local/synchronous-transmit")]
84
unsafe extern "C" {
85
#[link_name = "[future-new-1]start"]
86
fn future_new() -> u64;
87
}
88
#[cfg(not(target_arch = "wasm32"))]
89
unsafe extern "C" fn future_new() -> u64 {
90
unreachable!()
91
}
92
93
#[cfg(target_arch = "wasm32")]
94
#[link(wasm_import_module = "[export]local:local/synchronous-transmit")]
95
unsafe extern "C" {
96
#[link_name = "[future-write-1]start"]
97
fn future_write(_: u32, _: *const u8) -> u32;
98
}
99
#[cfg(not(target_arch = "wasm32"))]
100
unsafe extern "C" fn future_write(_: u32, _: *const u8) -> u32 {
101
unreachable!()
102
}
103
104
#[cfg(target_arch = "wasm32")]
105
#[link(wasm_import_module = "[export]local:local/synchronous-transmit")]
106
unsafe extern "C" {
107
#[link_name = "[future-read-1]start"]
108
fn future_read(_: u32, _: *mut u8) -> u32;
109
}
110
#[cfg(not(target_arch = "wasm32"))]
111
unsafe extern "C" fn future_read(_: u32, _: *mut u8) -> u32 {
112
unreachable!()
113
}
114
115
#[cfg(target_arch = "wasm32")]
116
#[link(wasm_import_module = "[export]local:local/synchronous-transmit")]
117
unsafe extern "C" {
118
#[link_name = "[future-drop-readable-1]start"]
119
fn future_drop_readable(_: u32);
120
}
121
#[cfg(not(target_arch = "wasm32"))]
122
unsafe extern "C" fn future_drop_readable(_: u32) {
123
unreachable!()
124
}
125
126
#[cfg(target_arch = "wasm32")]
127
#[link(wasm_import_module = "[export]local:local/synchronous-transmit")]
128
unsafe extern "C" {
129
#[link_name = "[future-drop-writable-1]start"]
130
fn future_drop_writable(_: u32);
131
}
132
#[cfg(not(target_arch = "wasm32"))]
133
unsafe extern "C" fn future_drop_writable(_: u32) {
134
unreachable!()
135
}
136
137
static STREAM_BYTES_TO_WRITE: &[u8] = &[1, 3, 5, 7, 11];
138
static FUTURE_BYTE_TO_WRITE: u8 = 13;
139
140
enum State {
141
S0 {
142
stream: u32,
143
stream_expected: Vec<u8>,
144
future: u32,
145
future_expected: u8,
146
},
147
S1 {
148
stream_tx: u32,
149
stream: u32,
150
stream_expected: Vec<u8>,
151
future_tx: u32,
152
future: u32,
153
future_expected: u8,
154
},
155
}
156
157
#[unsafe(export_name = "[async-lift]local:local/synchronous-transmit#start")]
158
unsafe extern "C" fn export_start(
159
stream: u32,
160
stream_expected: u32,
161
stream_expected_len: u32,
162
future: u32,
163
future_expected: u8,
164
) -> u32 {
165
let stream_expected_len = usize::try_from(stream_expected_len).unwrap();
166
167
unsafe {
168
context_set(
169
u32::try_from(Box::into_raw(Box::new(State::S0 {
170
stream,
171
stream_expected: Vec::from_raw_parts(
172
stream_expected as usize as *mut u8,
173
stream_expected_len,
174
stream_expected_len,
175
),
176
future,
177
future_expected,
178
})) as usize)
179
.unwrap(),
180
);
181
182
callback_start(EVENT_NONE, 0, 0)
183
}
184
}
185
186
#[unsafe(export_name = "[callback][async-lift]local:local/synchronous-transmit#start")]
187
unsafe extern "C" fn callback_start(event0: u32, _event1: u32, _event2: u32) -> u32 {
188
unsafe {
189
let state = &mut *(usize::try_from(context_get()).unwrap() as *mut State);
190
match state {
191
&mut State::S0 {
192
stream,
193
ref mut stream_expected,
194
future,
195
future_expected,
196
} => {
197
assert_eq!(event0, EVENT_NONE);
198
199
let pair = stream_new();
200
let stream_tx = u32::try_from(pair >> 32).unwrap();
201
let stream_rx = u32::try_from(pair & 0xFFFFFFFF_u64).unwrap();
202
203
let pair = future_new();
204
let future_tx = u32::try_from(pair >> 32).unwrap();
205
let future_rx = u32::try_from(pair & 0xFFFFFFFF_u64).unwrap();
206
207
task_return_start(
208
stream_rx,
209
STREAM_BYTES_TO_WRITE.as_ptr(),
210
STREAM_BYTES_TO_WRITE.len(),
211
future_rx,
212
FUTURE_BYTE_TO_WRITE,
213
);
214
215
*state = State::S1 {
216
stream_tx,
217
stream,
218
stream_expected: mem::take(stream_expected),
219
future_tx,
220
future,
221
future_expected,
222
};
223
224
CALLBACK_CODE_YIELD
225
}
226
227
&mut State::S1 {
228
stream_tx,
229
stream,
230
ref mut stream_expected,
231
future_tx,
232
future,
233
future_expected,
234
} => {
235
// Now we synchronously read and write and expect that the
236
// operations complete.
237
238
let mut buffer = vec![0_u8; stream_expected.len()];
239
let status = stream_read(stream, buffer.as_mut_ptr(), stream_expected.len());
240
assert_eq!(
241
status,
242
DROPPED | u32::try_from(stream_expected.len() << 4).unwrap()
243
);
244
assert_eq!(&buffer[..], stream_expected);
245
stream_drop_readable(stream);
246
247
let status = stream_write(
248
stream_tx,
249
STREAM_BYTES_TO_WRITE.as_ptr(),
250
STREAM_BYTES_TO_WRITE.len(),
251
);
252
assert_eq!(
253
status,
254
DROPPED | u32::try_from(STREAM_BYTES_TO_WRITE.len() << 4).unwrap()
255
);
256
stream_drop_writable(stream_tx);
257
258
let received = &mut 0_u8;
259
let status = future_read(future, received);
260
assert_eq!(status, COMPLETED);
261
assert_eq!(*received, future_expected);
262
future_drop_readable(future);
263
264
let status = future_write(future_tx, &FUTURE_BYTE_TO_WRITE);
265
assert_eq!(status, COMPLETED);
266
future_drop_writable(future_tx);
267
268
CALLBACK_CODE_EXIT
269
}
270
}
271
}
272
}
273
274
// Unused function; required since this file is built as a `bin`:
275
fn main() {}
276
277