diff --git a/gcli/executor.rs b/gcli/executor.rs new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/gcli/executor.rs @@ -0,0 +1 @@ + diff --git a/gcli/src/meta/executor.rs b/gcli/src/meta/executor.rs index ea32bbe8bf4..68464e0f22a 100644 --- a/gcli/src/meta/executor.rs +++ b/gcli/src/meta/executor.rs @@ -43,68 +43,30 @@ pub fn execute(wasm: &[u8], method: &str) -> Result> { let mut linker = >::new(); // Execution environment - // - // (import "env" "memory" (memory (;0;) 17)) - // (import "env" "gr_read" (func (;0;) (type 5))) - // (import "env" "alloc" (func (;1;) (type 6))) - // (import "env" "free" (func (;2;) (type 6))) - // (import "env" "gr_size" (func (;3;) (type 4))) - // (import "env" "gr_reply" (func (;4;) (type 5))) - // (import "env" "gr_panic" (func (;5;) (type 0))) - // (import "env" "gr_oom_panic" (func (;6;) (type 7))) { let memory = Memory::new(store.as_context_mut(), MemoryType::new(256, None)).unwrap(); - linker - .define("env", "memory", Extern::Memory(memory)) - .unwrap(); - - linker - .define("env", "gr_read", funcs::gr_read(&mut store, memory)) - .unwrap(); - - linker - .define("env", "alloc", funcs::alloc(&mut store, memory)) - .unwrap(); - - linker - .define("env", "free", funcs::free(&mut store)) - .unwrap(); - - linker - .define("env", "gr_size", funcs::gr_size(&mut store, memory)) - .unwrap(); - - linker - .define("env", "gr_reply", funcs::gr_reply(&mut store, memory)) - .unwrap(); - - linker - .define("env", "gr_panic", funcs::gr_panic(&mut store, memory)) - .unwrap(); - - linker - .define("env", "gr_oom_panic", funcs::gr_oom_panic(&mut store)) - .unwrap(); - - linker - .define("env", "gr_out_of_gas", funcs::gr_out_of_gas(&mut store)) - .unwrap(); + linker.define("env", "memory", Extern::Memory(memory))?; + linker.define("env", "gr_read", funcs::gr_read(&mut store, memory))?; + linker.define("env", "alloc", funcs::alloc(&mut store, memory))?; + linker.define("env", "free", funcs::free(&mut store))?; + linker.define("env", "gr_size", funcs::gr_size(&mut store, memory))?; + linker.define("env", "gr_reply", funcs::gr_reply(&mut store, memory))?; + linker.define("env", "gr_panic", funcs::gr_panic(&mut store, memory))?; + linker.define("env", "gr_oom_panic", funcs::gr_oom_panic(&mut store))?; + linker.define("env", "gr_out_of_gas", funcs::gr_out_of_gas(&mut store))?; } let instance = linker .instantiate(&mut store, &module) .unwrap() - .start(&mut store) - .unwrap(); + .start(&mut store)?; let metadata = instance .get_export(&store, method) .and_then(Extern::into_func) - .ok_or_else(|| anyhow!("could not find function \"metadata\"")) - .unwrap() - .typed::<(), (), _>(&mut store) - .unwrap(); + .ok_or_else(|| anyhow!("could not find function \"metadata\""))? + .typed::<(), (), _>(&mut store)?; - metadata.call(&mut store, ()).unwrap(); + metadata.call(&mut store, ())?; Ok(store.state().msg.clone()) } diff --git a/gcli/src/meta/funcs.rs b/gcli/src/meta/funcs.rs index 3cdd9569e87..5cbdf26d981 100644 --- a/gcli/src/meta/funcs.rs +++ b/gcli/src/meta/funcs.rs @@ -18,7 +18,8 @@ use super::executor::HostState; use wasmi::{ - core::memory_units::Pages, AsContext, AsContextMut, Caller, Extern, Func, Memory, Store, + core::{memory_units::Pages, Trap, TrapCode}, + AsContext, AsContextMut, Caller, Extern, Func, Memory, Store, }; pub fn alloc(store: &mut Store, memory: Memory) -> Extern { @@ -46,22 +47,7 @@ pub fn free(ctx: impl AsContextMut) -> Extern { pub fn gr_panic(ctx: &mut Store, _memory: Memory) -> Extern { Extern::Func(Func::wrap( ctx, - move |mut _caller: Caller<'_, HostState>, _ptr: u32, _len: i32| { - // let (ptr, len) = (ptr as usize, len as usize); - // - // let mut msg = vec![0; len]; - // memory - // .clone() - // .read(ctx.as_context(), ptr, &mut msg) - // .map_err(|e| { - // log::error!("{:?}", e); - // // Trap::i32_exit(1) - // }) - // .unwrap(); - // - // log::error!("panic occurred: {:?}", String::from_utf8_lossy(&msg)); - // Ok(()) - }, + move |mut _caller: Caller<'_, HostState>, _ptr: u32, _len: i32| {}, )) } @@ -83,9 +69,7 @@ pub fn gr_read(ctx: &mut Store, memory: Memory) -> Extern { if at + len <= msg.len() { payload.copy_from_slice(&msg[at..(at + len)]); } else { - log::error!("overflow"); - // return Err(Trap::i32_exit(1)); - return Ok(()); + return Err(Trap::Code(TrapCode::MemoryAccessOutOfBounds)); } let len: u32 = memory @@ -100,30 +84,28 @@ pub fn gr_read(ctx: &mut Store, memory: Memory) -> Extern { .write(caller.as_context_mut(), err, &len.to_le_bytes()) .map_err(|e| { log::error!("{:?}", e); - // Trap::i32_exit(1) - }) - .unwrap(); + Trap::Code(TrapCode::MemoryAccessOutOfBounds) + })?; Ok(()) }, )) } -/// # NOTE -/// -/// Just for the compatibility with the program metadata pub fn gr_reply(ctx: &mut Store, memory: Memory) -> Extern { Extern::Func(Func::wrap( ctx, move |mut caller: Caller<'_, HostState>, ptr: u32, len: i32, _value: i32, _err: i32| { - // TODO: process payload from here. - let len = len as usize; - let mut result = vec![0; len]; + let mut result = vec![0; len as usize]; + memory .read(caller.as_context(), ptr as usize, &mut result) - .unwrap(); - + .map_err(|e| { + log::error!("{:?}", e); + Trap::Code(TrapCode::MemoryAccessOutOfBounds) + })?; caller.host_data_mut().msg = result; + Ok(()) }, )) @@ -144,8 +126,8 @@ pub fn gr_size(ctx: &mut Store, memory: Memory) -> Extern { ) .map_err(|e| { log::error!("{:?}", e); - }) - .unwrap(); + Trap::Code(TrapCode::MemoryAccessOutOfBounds) + })?; Ok(()) }, diff --git a/gcli/src/result.rs b/gcli/src/result.rs index 8b6e2546509..621cd7e41ef 100644 --- a/gcli/src/result.rs +++ b/gcli/src/result.rs @@ -65,6 +65,8 @@ pub enum Error { InvalidWasm, #[error("Wasm execution error {0}")] WasmExecution(String), + #[error("Wasmi execution error {0}")] + Wasmi(wasmi::Error), #[error(transparent)] Etc(#[from] etc::Error), #[error("Metadata parsing error {0:?}")]