1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
use crate::{helpers::map_js_error, *};
use js_sys::{Uint8Array, WebAssembly};

#[derive(Clone, Debug)]
pub struct Module {
    pub(crate) module: WebAssembly::Module,
}

impl Module {
    pub fn new(_engine: &Engine, bytes: impl AsRef<[u8]>) -> Result<Self> {
        let bytes = bytes.as_ref();
        Self::from_bytes(bytes).or_else(|err| Self::from_wat(bytes, err))
    }

    #[cfg(feature = "wat")]
    fn from_wat(wat: &[u8], original_err: Error) -> Result<Self> {
        // If it's not text, give back the original error, it's probably more useful
        let text: &str = std::str::from_utf8(wat).map_err(move |_| original_err)?;

        let bytes = wat::parse_str(text)?;

        Self::from_bytes(&bytes)
    }

    #[cfg(not(feature = "wat"))]
    fn from_wat(_wat: &[u8], original_err: Error) -> Result<Self> {
        // TODO: Add the "enable wat" warning if _wat is valid utf-8?
        Err(original_err)
    }

    fn from_bytes(bytes: &[u8]) -> Result<Self> {
        // TODO: view might be faster than from, but its unsafe
        // Uint8Array::view(bytes.as_ref());

        let byte_array = Uint8Array::from(bytes);
        let module = WebAssembly::Module::new(&byte_array.into())
            .map_err(map_js_error("New WebAssembly module from bytes"))?;
        Ok(Self { module })
    }
}