Commit 0da4a41f authored by Guy Watson's avatar Guy Watson
Browse files

Wasmer Github issue closed

parent ab9215bb
[package]
name = "load-wasmer"
version = "0.2.0"
authors = ["Guy Watson <guy.watson@utah.edu>"]
edition = "2018"
[dependencies]
# Uses the path to the repo when used locally, and uses
# version 1.0.2 from crates.io when published.
anyhow = "1.0.38"
crc = "1.8.1"
lazy_static = "1.4.0"
structopt = "0.3.21"
### Enable these for use on the testing machines (for fresh-built from source)
# wasmer = { path = "/local/work/wasmer/lib/api" }
# wasmer-compiler-singlepass = { path = "/local/work/wasmer/lib/compiler-singlepass" }
# wasmer-compiler-cranelift = { path = "/local/work/wasmer/lib/compiler-cranelift" }
# wasmer-compiler-llvm = { path = "/local/work/wasmer/lib/compiler-llvm" }
# wasmer-engine-universal = { path = "/local/work/wasmer/lib/engine-universal", features = ["compiler"] }
# wasmer-engine-dylib = { path = "/local/work/wasmer/lib/engine-dylib", features = ["compiler"] }
# wasmer-engine-staticlib = { path = "/local/work/wasmer/lib/engine-staticlib", features = ["compiler"] }
### Enable these for local development with an already set up rust environment
wasmer = { version = "2.0.0" }
wasmer-compiler-singlepass = { version = "2.0.0" }
wasmer-compiler-cranelift = { version = "2.0.0" }
wasmer-compiler-llvm = { version = "2.0.0" }
wasmer-engine-universal = { version = "2.0.0", features = ["compiler"] }
wasmer-engine-dylib = { version = "2.0.0", features = ["compiler"] }
wasmer-engine-staticlib = { version = "2.0.0", features = ["compiler"] }
//use std::env;
use std::fs;
use structopt::StructOpt;
use wasmer::{imports, Instance, Module, NativeFunc, Store, Function};
use wasmer_compiler_cranelift::Cranelift;
use wasmer_engine_universal::Universal;
use wasmer_engine_dylib::Dylib;
use wasmer_engine_staticlib::Staticlib;
use crc::{crc32, Hasher32};
use std::sync::Mutex;
#[macro_use]
extern crate lazy_static;
lazy_static! {
static ref CRC_VAL: Mutex<crc32::Digest> = Mutex::new(crc32::Digest::new(crc32::IEEE));
}
// Add a value to the crc. This function is imported by the wasm code
fn add_to_crc(new_val : i32) {
CRC_VAL.lock().unwrap().write(&new_val.to_le_bytes());
}
fn get_crc() -> String {
format!("{:x}",CRC_VAL.lock().unwrap().sum32())
}
/// Run a wasm program using Wasmer
#[derive(StructOpt)]
#[structopt(name = "load-wasmer", about = "Uses Wasmer to load and execute a WebAssembly program.")]
struct Cli {
/// Engine. Options are "universal", "dylib" or "staticlib".
#[structopt(long, required(true))]
engine: String,
/// The path to the wasm program (.wasm).
#[structopt(required(true))]
program: std::path::PathBuf,
}
fn main() -> anyhow::Result<()> {
let args = Cli::from_args();
// Get command line arguments
if !(args.engine == "universal"
|| args.engine == "dylib"
|| args.engine == "staticlib") {
panic!("Provided engine option must be [\"universal\"|\"dylib\"|\"staticlib\"]");
}
// Insantiate the compiler and engine into a store
let engine = &args.engine[..];
let compiler = Cranelift::new();
let store = match engine {
"universal" => Store::new(&Universal::new(compiler).engine()),
"dylib" => Store::new(&Dylib::new(compiler).engine()),
"staticlib" => Store::new(&Staticlib::new(compiler).engine()),
_ => panic!("engine did not match any known option"),
};
let wasm_bytes = fs::read(args.program)?;
//println!("Compiling module...");
// Let's compile the Wasm module.
let module = Module::new(&store, wasm_bytes)?;
// Create a function to pass to wasm
let add_to_crc_func = Function::new_native(
&store,
add_to_crc
);
// Create an import object with the crc function.
let import_object = imports! {
"env" => {
"addToCrc" => add_to_crc_func
},
};
//println!("Instantiating module...");
// Let's instantiate the Wasm module.
let instance = Instance::new(&module, &import_object)?;
// Get handles for the exports
let main_func: NativeFunc<(), i32> = instance.exports.get_native_function("_main")?;
let crc_globals_func: NativeFunc<(), ()> = instance.exports.get_native_function("_crc_globals")?;
let memory = instance.exports.get_memory("_memory")?;
// Call main and add the result to the crc
add_to_crc(main_func.call()?);
// Call the crc globals function to have wasm add all of it's globals to the crc
crc_globals_func.call()?;
// Add the contents of memory to the crc
// Get the pointer and size in bytes
let mem_ptr: *mut i32 = memory.data_ptr() as *mut i32;
let mem_size = (memory.data_size() / 4) as isize; // bytes to i32s
for address in 0..mem_size {
let mem_value;
unsafe {
mem_value = *mem_ptr.offset(address);
}
add_to_crc(mem_value);
}
// Print the crc
println!("{}", get_crc());
Ok(())
}
(module
(type (;0;) (func (param i32)))
(type (;1;) (func (result i32)))
(type (;2;) (func (param f64) (result f64)))
(type (;3;) (func))
(import "env" "addToCrc" (func (;0;) (type 0)))
(func (;1;) (type 1) (result i32)
(local i32 i64 f32 f64 i32 f64 i32)
i32.const 698)
(func (;2;) (type 3)
(local i64))
(memory (;0;) 1)
(export "_memory" (memory 0))
(export "_main" (func 1))
(export "_crc_globals" (func 2)))
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment