diff --git a/rust-runner/.gitignore b/rust-runner/.gitignore new file mode 100644 index 0000000..f2f9e58 --- /dev/null +++ b/rust-runner/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock \ No newline at end of file diff --git a/rust-runner/Cargo.toml b/rust-runner/Cargo.toml new file mode 100644 index 0000000..efc0b4a --- /dev/null +++ b/rust-runner/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rust-runner" +version = "0.1.0" +authors = ["NikVolf "] + +[dependencies] +parity-wasm = { git="https://github.com/nikvolf/parity-wasm" } +wasm-utils = { path = "../" } \ No newline at end of file diff --git a/rust-runner/src/alloc.rs b/rust-runner/src/alloc.rs new file mode 100644 index 0000000..bd17625 --- /dev/null +++ b/rust-runner/src/alloc.rs @@ -0,0 +1,22 @@ +use parity_wasm::interpreter::ModuleInstanceInterface; + +pub struct Arena { + dynamic_top: u32, +} + +pub struct Error; + +impl Arena { + pub fn new(stack_top: u32) -> Self { + MemoryArenaAllocator { + module: module, + dynamic_top: stack_top, + } + } + + fn alloc(&mut self, size: u32) -> Result { + let previous_top = self.dynamic_top; + self.dynamic_top += size; + Ok(previous_top) + } +} \ No newline at end of file diff --git a/rust-runner/src/main.rs b/rust-runner/src/main.rs new file mode 100644 index 0000000..9b845dc --- /dev/null +++ b/rust-runner/src/main.rs @@ -0,0 +1,41 @@ +/* + + Rust contract demo runner + +*/ + +extern crate parity_wasm; +extern crate wasm_utils; + +mod alloc; +mod storage; + +use std::env; + +fn main() { + /// First, load wasm contract as a module + + wasm_utils::init_log(); + + let args = env::args().collect::>(); + if args.len() != 2 { + println!("Usage: {} contract.wasm", args[0]); + return; + } + + let module = parity_wasm::deserialize_file(&args[1]).expect("Module deserialization to succeed"); + + /// Second, create program instance + let program = parity_wasm::interpreter::ProgramInstance::new().expect("Program instance to be created"); + + /// Add module to the programm + program.add_module("contract", module); + + /// Create allocator + let mut allocator = alloc::Arena::new(5*1024*1024); + + + /// Invoke _call method of the module + + /// ??? +} \ No newline at end of file diff --git a/rust-runner/src/storage.rs b/rust-runner/src/storage.rs new file mode 100644 index 0000000..0ead7b4 --- /dev/null +++ b/rust-runner/src/storage.rs @@ -0,0 +1,49 @@ +use parity_wasm::interpreter::ModuleInstanceInterface; +use parity_wasm::interpreter::ItemIndex; +use std::sync::Arc; + +const DEFAULT_MEMORY_INDEX: ItemIndex = ItemIndex(0); + +pub struct Storage { + data: Vec, + module: Arc, +} + +pub struct Error; + +impl Storage { + + pub fn read(&self, offset: u32, len: u32, dst: u32) -> i32 { + let memory = match self.module.memory(DEFAULT_MEMORY_INDEX) { + Err(_) => { return -1; }, + Ok(memory) => memory, + }; + + match memory.set(dst, &self.data[offset as usize..offset as usize + len as usize]) { + Err(_) => { return -1; } + Ok(_) => return len; + } + } + + pub fn write(&mut self, offset: u32, len: u32, src: u32) -> i32 { + let memory = match self.module.memory(DEFAULT_MEMORY_INDEX) { + Err(_) => { return -1; }, + Ok(memory) => memory, + }; + + let slice = match memory.get(src, len as usize) { + Err(_) => { return -1; } + Ok(slice) => return slice; + }; + + if self.data.len() < offset as usize + slice.len { + self.data.reserve(offset as usize + slice.len); + unsafe { + self.data.set_len(offset as usize + slice.len); + } + } + self.data[offset as usize..offset as usize + slice.len].copy_from_slice(&slice[..]); + } + + pub fn size(&self) -> u32 { self.data.len() as u32 } +} \ No newline at end of file