wasmy-vm 0.5.1

virtual machine of wasmy (easily customize my wasm app)
Documentation
use std::collections::HashMap;
use std::sync::RwLock;

use lazy_static;
use wasmer::{Module, Store, Type};
use wasmer_compiler_cranelift::Cranelift;
use wasmer_engine_universal::Universal;

use crate::handler::WasmHandlerApi;

use crate::{VmHandlerApi, WasmFile, WasmUri};

lazy_static::lazy_static! {
   pub(crate) static ref MODULES: RwLock<HashMap<WasmUri, Module>> = RwLock::new(HashMap::new());
}

pub(crate) fn load<B, W>(wasm_file: W) -> anyhow::Result<WasmUri>
    where B: AsRef<[u8]>,
          W: WasmFile<B>,
{
    // collect and register handlers once
    VmHandlerApi::collect_and_register_once();
    let (wasm_uri, bytes) = wasm_file.into_parts()?;

    #[cfg(debug_assertions)] println!("compiling module, wasm_uri={}...", wasm_uri);
    let store: Store = Store::new(&Universal::new(Cranelift::default()).engine());
    let mut module = Module::new(&store, bytes)?;
    module.set_name(wasm_uri.as_str());

    for function in module.exports().functions() {
        let name = function.name();
        if name == WasmHandlerApi::onload_symbol() {
            let ty = function.ty();
            if ty.params().len() > 0 || ty.results().len() > 0 {
                return Err(anyhow::Error::msg(format!("Incompatible Export Type: fn {}(){{}}", WasmHandlerApi::onload_symbol())));
            }
            continue;
        }
        WasmHandlerApi::symbol_to_method(name).map_or_else(|| {
            #[cfg(debug_assertions)]println!("module exports function(invalid for vm): {:?}", function);
        }, |_method| {
            let ty = function.ty();
            if ty.results().len() == 0 && ty.params().eq(&[Type::I32, Type::I32]) {
                #[cfg(debug_assertions)]println!("module exports function(valid for vm): {:?}", function);
            } else {
                #[cfg(debug_assertions)]println!("module exports function(invalid for vm): {:?}", function);
            }
        });
    }

    MODULES.write().unwrap().insert(wasm_uri.clone(), module);

    #[cfg(debug_assertions)] println!("loaded module, wasm_uri={}", wasm_uri);

    Ok(wasm_uri.clone())
}