diff --git a/rust-runner/src/alloc.rs b/rust-runner/src/alloc.rs index ffb29cf..92c046e 100644 --- a/rust-runner/src/alloc.rs +++ b/rust-runner/src/alloc.rs @@ -4,6 +4,7 @@ pub struct Arena { dynamic_top: u32, } +#[derive(Debug)] pub struct Error; impl Arena { @@ -13,7 +14,7 @@ impl Arena { } } - fn alloc(&mut self, size: u32) -> Result { + pub fn alloc(&mut self, size: u32) -> Result { let previous_top = self.dynamic_top; self.dynamic_top += size; Ok(previous_top) diff --git a/rust-runner/src/call_args.rs b/rust-runner/src/call_args.rs new file mode 100644 index 0000000..08457be --- /dev/null +++ b/rust-runner/src/call_args.rs @@ -0,0 +1,61 @@ +use parity_wasm::interpreter::{self, ModuleInstanceInterface}; +use alloc; + +use {DEFAULT_MEMORY_INDEX, WasmMemoryPtr}; + +fn write_u32(dst: &mut [u8], val: u32) { + dst[0] = (val & 0x000000ff) as u8; + dst[1] = ((val & 0x0000ff00) >> 8) as u8; + dst[2] = ((val & 0x00ff0000) >> 16) as u8; + dst[3] = ((val & 0xff000000) >> 24) as u8; +} + +#[derive(Debug)] +pub enum Error { + Allocator(alloc::Error), + Interpreter(interpreter::Error), +} + +impl From for Error { + fn from(err: alloc::Error) -> Self { + Error::Allocator(err) + } +} + +impl From for Error { + fn from(err: interpreter::Error) -> Self { + Error::Interpreter(err) + } +} + +pub fn init( + env: &interpreter::ModuleInstanceInterface, + allocator: &mut alloc::Arena, + context: &[u8], + input: &[u8], +) -> Result { + let mut context_ptr_slc = [0u8; 4]; + let mut context_length = [0u8; 4]; + let mut input_ptr_slc = [0u8; 4]; + let mut input_length = [0u8; 4]; + + let descriptor_ptr = allocator.alloc(16)?; + let context_ptr = allocator.alloc(context.len() as u32)?; + let input_ptr = allocator.alloc(input.len() as u32)?; + + write_u32(&mut context_ptr_slc, context_ptr); + write_u32(&mut context_length, context.len() as u32); + write_u32(&mut input_ptr_slc, input_ptr); + write_u32(&mut input_length, input.len() as u32); + + let memory = env.memory(DEFAULT_MEMORY_INDEX)?; + + memory.set(descriptor_ptr, &context_ptr_slc)?; + memory.set(descriptor_ptr+4, &context_length)?; + memory.set(descriptor_ptr+8, &input_ptr_slc)?; + memory.set(descriptor_ptr+12, &input_length)?; + memory.set(context_ptr, context)?; + memory.set(input_ptr, input)?; + + Ok(descriptor_ptr as i32) +} \ No newline at end of file diff --git a/rust-runner/src/main.rs b/rust-runner/src/main.rs index 22940fb..0e6e7dd 100644 --- a/rust-runner/src/main.rs +++ b/rust-runner/src/main.rs @@ -9,9 +9,13 @@ extern crate wasm_utils; mod alloc; mod storage; +mod call_args; use std::env; -use parity_wasm::interpreter::ModuleInstanceInterface; +use parity_wasm::interpreter::{self, ModuleInstanceInterface, RuntimeValue}; + +pub const DEFAULT_MEMORY_INDEX: interpreter::ItemIndex = interpreter::ItemIndex::Internal(0); +pub type WasmMemoryPtr = i32; fn main() { // First, load wasm contract as a module @@ -34,8 +38,16 @@ fn main() { // Create allocator let mut allocator = alloc::Arena::new(5*1024*1024); + // Initialize call descriptor + let descriptor = call_args::init( + &*program.module("env").expect("env module to exist"), + &mut allocator, + &[], + &[0u8; 128], + ).expect("call descriptor initialization to succeed"); + // Invoke _call method of the module - module_instance.execute_export("_call", vec![]).expect("_call to execute successfully"); + module_instance.execute_export("_call", vec![descriptor.into()]).expect("_call to execute successfully"); // ??? } \ No newline at end of file diff --git a/rust-runner/src/storage.rs b/rust-runner/src/storage.rs index 70412f2..f35e2bd 100644 --- a/rust-runner/src/storage.rs +++ b/rust-runner/src/storage.rs @@ -2,7 +2,7 @@ use parity_wasm::interpreter::ModuleInstanceInterface; use parity_wasm::interpreter::ItemIndex; use std::sync::Arc; -const DEFAULT_MEMORY_INDEX: ItemIndex = ItemIndex::Internal(0); +use DEFAULT_MEMORY_INDEX; pub struct Storage { data: Vec,