Skip to main content

elytra_wasm/
lib.rs

1use std::io::Write;
2
3#[macro_export]
4macro_rules! elytra_wasm {
5    ( $e:expr ) => {
6
7        thread_local! {
8            static ELYTRA_WASM_OUT: std::cell::Cell<[u64; 8]> = std::cell::Cell::new([0; 8]);
9        }
10
11        #[allow(unused)]
12        #[unsafe(no_mangle)]
13        pub extern "C" fn send(a: u64, b: u64, c: u64, d: u64, e: u64, f: u64, g: u64, h: u64) -> u8 {
14            let in_bytes = elytra_wasm::unpack64([a, b, c, d, e, f, g, h]);
15            let res = match elytra_conf::command::Command::from_bytes(&in_bytes) {
16                Ok(command) => $e(command),
17                Err(e) => elytra_conf::command::CommandResponse::error(e)
18            };
19            if let Ok(res_bytes) = res.as_bytes().try_into() {
20                ELYTRA_WASM_OUT.set(elytra_wasm::pack64(res_bytes));
21                return 8;
22            } else {
23                return 0;
24            }
25        }
26
27        #[allow(unused)]
28        #[unsafe(no_mangle)]
29        pub extern "C" fn recieve(index: usize) -> u64 {
30            ELYTRA_WASM_OUT.get().get(index).copied().unwrap_or_default()
31        }
32
33    };
34}
35
36
37pub fn sync_await<T, F: Future<Output = T>>(fut: F) -> T {
38    use std::task::Poll::*;
39    use std::pin::pin;
40    use std::task::{Context, Waker};
41
42    let mut pin = pin!(fut);
43    let mut ctx = Context::from_waker(Waker::noop());
44    loop {
45        match pin.as_mut().poll(&mut ctx) {
46            Ready(res) => {
47                return res;
48            },
49            Pending => {},
50        }
51    }
52}
53
54pub fn unpack64(value: [u64; 8]) -> [u8; 64] {
55    let mut buf = [0u8; 64];
56    let mut cursor = buf.as_mut_slice();
57    for v in value {
58        let _ = cursor.write(&v.to_be_bytes());
59    }
60    buf
61}
62
63pub fn pack64(value: [u8; 64]) -> [u64; 8]  {
64    let mut buf = [0u64; 8];
65    for (i, bytes) in value.chunks(8).enumerate() {
66        let bytes = bytes.try_into()
67            .expect("input array should cleanly be divisible by 8");
68        buf[i] = u64::from_be_bytes(bytes);
69    }
70    buf
71}