From 9754cf83bef8332d331033fce91d2c25b2bba76a Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 22 Dec 2015 15:17:28 +0100 Subject: [PATCH 1/7] jit improvements in progress --- rust-evmjit/src/lib.rs | 146 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 144 insertions(+), 2 deletions(-) diff --git a/rust-evmjit/src/lib.rs b/rust-evmjit/src/lib.rs index b7742e5fb..29b93df36 100644 --- a/rust-evmjit/src/lib.rs +++ b/rust-evmjit/src/lib.rs @@ -30,6 +30,36 @@ pub struct JitRuntimeData { pub code_hash: JitI256 } +/// Component oriented safe handle to `JitRuntimeData`. +pub struct RuntimeDataHandle { + runtime_data: *mut JitRuntimeData +} + +impl RuntimeDataHandle { + /// Creates new handle. + pub unsafe fn new() -> Self { + RuntimeDataHandle { + runtime_data: evmjit_create_runtime_data() + } + } + + /// Returns immutable reference to runtime data. + pub unsafe fn runtime_data(&self) -> &JitRuntimeData { + &*self.runtime_data + } + + /// Returns mutable reference to runtime data. + pub unsafe fn mut_runtime_data(&mut self) -> &mut JitRuntimeData { + &mut *self.runtime_data + } +} + +impl Drop for RuntimeDataHandle { + fn drop(&mut self) { + unsafe { evmjit_destroy_runtime_data(self.runtime_data) } + } +} + #[repr(C)] #[derive(Debug, Eq, PartialEq)] pub enum JitReturnCode { @@ -43,14 +73,124 @@ pub enum JitReturnCode { UnexpectedError = -111 } +/// JitContext struct declaration. pub enum JitContext {} +pub struct ContextHandle { + data_handle: RuntimeDataHandle, + env: Env, + context: *mut JitContext +} + +impl ContextHandle { + pub unsafe fn new(mut data_handle: RuntimeDataHandle, env: Env) -> Self { + // TODO: context should take env + let context = evmjit_create_context(data_handle.mut_runtime_data(), &mut 0); + ContextHandle { + data_handle: data_handle, + env: env, + context: context + } + } +} + +/// Component oriented wrapper around jit env c interface. +pub trait JitEnv { + fn sload(&mut self); +} + +/// C abi compatible wrapper for JitEnvTrait implementers. +pub struct Env { + env_impl: Option> +} + +impl Env { + pub fn new(env_impl: T) -> Self where T: JitEnv + 'static { + Env { env_impl: Some(Box::new(env_impl)) } + } +} + +impl JitEnv for Env { + fn sload(&mut self) { + if let Some(ref mut env) = self.env_impl { + env.sload(); + } + } +} + +#[no_mangle] +pub unsafe extern fn env_sload(env: *mut Env, _index: *const JitI256, _value: *const JitI256) { + let env = &mut *env; + env.sload(); +} + +#[no_mangle] +pub extern fn env_sstore(_env: *mut Env, _index: *const JitI256, _value: *const JitI256) { + unimplemented!() +} + +#[no_mangle] +pub extern fn env_balance(_env: *mut Env, _address: *const JitI256, _value: *const JitI256) { + unimplemented!() +} + +#[no_mangle] +pub extern fn env_blockhash(_env: *mut Env, _number: *const JitI256, _hash: *const JitI256) { + unimplemented!() +} + +#[no_mangle] +pub extern fn env_create(_env: *mut Env, + _io_gas: *const u64, + _endowment: *const JitI256, + _init_beg: *const u8, + _init_size: *const u64, + _address: *const JitI256) { + unimplemented!() +} + +#[no_mangle] +pub extern fn env_call(_env: *mut Env, + _io_gas: *const u64, + _call_gas: *const u64, + _receive_address: *const JitI256, + _value: *const JitI256, + _in_beg: *const u8, + _in_size: *const u64, + _out_beg: *const u8, + _out_size: *const u64, + _code_address: JitI256) { + unimplemented!() +} + +#[no_mangle] +pub extern fn env_sha3(_begin: *const u8, _size: *const u64, _hash: *const JitI256) { + unimplemented!() +} + +#[no_mangle] +pub extern fn env_extcode(_env: *mut Env, _address: *const JitI256, _size: *const u64) { + unimplemented!() +} + +#[no_mangle] +pub extern fn env_log(_env: *mut Env, + _beg: *const u8, + _size: *const u64, + _topic1: *const JitI256, + _topic2: *const JitI256, + _topic3: *const JitI256, + _topic4: *const JitI256) { + unimplemented!() +} + + #[link(name="evmjit")] extern "C" { pub fn evmjit_create_runtime_data() -> *mut JitRuntimeData; pub fn evmjit_destroy_runtime_data(data: *mut JitRuntimeData); - pub fn evmjit_create_context(data: *mut JitRuntimeData, env: u8) -> *mut JitContext; + pub fn evmjit_create_context(data: *mut JitRuntimeData, env: *mut u8) -> *mut JitContext; pub fn evmjit_destroy_context(context: *mut JitContext); pub fn evmjit_exec(context: *mut JitContext) -> JitReturnCode; @@ -60,8 +200,10 @@ extern "C" { #[test] fn it_works() { unsafe { + let mut env = 0u8; + let data = evmjit_create_runtime_data(); - let context = evmjit_create_context(data, 0); + let context = evmjit_create_context(data, &mut env); let code = evmjit_exec(context); assert_eq!(code, JitReturnCode::Stop); From 61a4b59da5db0c9f28083478dee82bf70e99f784 Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 22 Dec 2015 16:27:19 +0100 Subject: [PATCH 2/7] safe handles and docs --- rust-evmjit/src/lib.rs | 73 +++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/rust-evmjit/src/lib.rs b/rust-evmjit/src/lib.rs index 29b93df36..b3220652d 100644 --- a/rust-evmjit/src/lib.rs +++ b/rust-evmjit/src/lib.rs @@ -3,7 +3,6 @@ //! Requires latest version of Ethereum EVM JIT. https://github.com/debris/evmjit extern crate libc; -use std::ptr; #[repr(C)] pub struct JitI256 { @@ -37,20 +36,20 @@ pub struct RuntimeDataHandle { impl RuntimeDataHandle { /// Creates new handle. - pub unsafe fn new() -> Self { + pub fn new() -> Self { RuntimeDataHandle { - runtime_data: evmjit_create_runtime_data() + runtime_data: unsafe { evmjit_create_runtime_data() } } } /// Returns immutable reference to runtime data. - pub unsafe fn runtime_data(&self) -> &JitRuntimeData { - &*self.runtime_data + pub fn runtime_data(&self) -> &JitRuntimeData { + unsafe { &*self.runtime_data } } /// Returns mutable reference to runtime data. - pub unsafe fn mut_runtime_data(&mut self) -> &mut JitRuntimeData { - &mut *self.runtime_data + pub fn mut_runtime_data(&mut self) -> &mut JitRuntimeData { + unsafe { &mut *self.runtime_data } } } @@ -76,22 +75,32 @@ pub enum JitReturnCode { /// JitContext struct declaration. pub enum JitContext {} +/// Safe handle for jit context. pub struct ContextHandle { - data_handle: RuntimeDataHandle, - env: Env, - context: *mut JitContext + context: *mut JitContext, + _data_handle: RuntimeDataHandle } impl ContextHandle { - pub unsafe fn new(mut data_handle: RuntimeDataHandle, env: Env) -> Self { - // TODO: context should take env - let context = evmjit_create_context(data_handle.mut_runtime_data(), &mut 0); + /// Creates new context handle. + pub fn new(mut data_handle: RuntimeDataHandle, mut env: Env) -> Self { + let context = unsafe { evmjit_create_context(data_handle.mut_runtime_data(), &mut env) }; ContextHandle { - data_handle: data_handle, - env: env, - context: context + context: context, + _data_handle: data_handle } } + + /// Executes context. + pub fn exec(&mut self) -> JitReturnCode { + unsafe { evmjit_exec(self.context) } + } +} + +impl Drop for ContextHandle { + fn drop(&mut self) { + unsafe { evmjit_destroy_context(self.context); } + } } /// Component oriented wrapper around jit env c interface. @@ -105,15 +114,23 @@ pub struct Env { } impl Env { + /// Creates new environment wrapper for given implementation pub fn new(env_impl: T) -> Self where T: JitEnv + 'static { Env { env_impl: Some(Box::new(env_impl)) } } + + /// Creates empty environment. + /// It can be used to for any operations. + pub fn empty() -> Self { + Env { env_impl: None } + } } impl JitEnv for Env { fn sload(&mut self) { - if let Some(ref mut env) = self.env_impl { - env.sload(); + match self.env_impl { + Some(ref mut env) => env.sload(), + None => { panic!(); } } } } @@ -189,21 +206,22 @@ pub extern fn env_log(_env: *mut Env, extern "C" { pub fn evmjit_create_runtime_data() -> *mut JitRuntimeData; pub fn evmjit_destroy_runtime_data(data: *mut JitRuntimeData); - - pub fn evmjit_create_context(data: *mut JitRuntimeData, env: *mut u8) -> *mut JitContext; pub fn evmjit_destroy_context(context: *mut JitContext); - pub fn evmjit_exec(context: *mut JitContext) -> JitReturnCode; +} +#[link(name="evmjit")] +// Env does not have to by a C type +#[allow(improper_ctypes)] +extern "C" { + pub fn evmjit_create_context(data: *mut JitRuntimeData, env: *mut Env) -> *mut JitContext; } #[test] -fn it_works() { +fn ffi_test() { unsafe { - let mut env = 0u8; - let data = evmjit_create_runtime_data(); - let context = evmjit_create_context(data, &mut env); + let context = evmjit_create_context(data, &mut Env::empty()); let code = evmjit_exec(context); assert_eq!(code, JitReturnCode::Stop); @@ -213,3 +231,8 @@ fn it_works() { } } +#[test] +fn handle_test() { + let mut context = ContextHandle::new(RuntimeDataHandle::new(), Env::empty()); + assert_eq!(context.exec(), JitReturnCode::Stop); +} From ff747ba3498549642b8b18ce43acdc6d057eafab Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 22 Dec 2015 17:00:30 +0100 Subject: [PATCH 3/7] docs --- rust-evmjit/src/lib.rs | 267 ++++++++++++++++++++++------------------- 1 file changed, 145 insertions(+), 122 deletions(-) diff --git a/rust-evmjit/src/lib.rs b/rust-evmjit/src/lib.rs index b3220652d..ae641e045 100644 --- a/rust-evmjit/src/lib.rs +++ b/rust-evmjit/src/lib.rs @@ -1,33 +1,22 @@ //! Bare rust wrapper around evmjit //! //! Requires latest version of Ethereum EVM JIT. https://github.com/debris/evmjit +//! +//! ``` +//! extern crate evmjit; +//! use evmjit::*; +//! +//! fn main() { +//! let mut context = ContextHandle::new(RuntimeDataHandle::new(), EnvHandle::empty()); +//! assert_eq!(context.exec(), ReturnCode::Stop); +//! } +//! +//! ``` extern crate libc; +use self::ffi::*; -#[repr(C)] -pub struct JitI256 { - pub words: [u64; 4] -} - -#[repr(C)] -pub struct JitRuntimeData { - pub gas: i64, - pub gas_price: i64, - pub call_data: *const libc::c_char, - pub call_data_size: u64, - pub address: JitI256, - pub caller: JitI256, - pub origin: JitI256, - pub call_value: JitI256, - pub coinbase: JitI256, - pub difficulty: JitI256, - pub gas_limit: JitI256, - pub number: u64, - pub timestamp: i64, - pub code: *const libc::c_char, - pub code_size: u64, - pub code_hash: JitI256 -} +pub use self::ffi::JitReturnCode as ReturnCode; /// Component oriented safe handle to `JitRuntimeData`. pub struct RuntimeDataHandle { @@ -59,22 +48,6 @@ impl Drop for RuntimeDataHandle { } } -#[repr(C)] -#[derive(Debug, Eq, PartialEq)] -pub enum JitReturnCode { - Stop = 0, - Return = 1, - Suicide = 2, - - OutOfGas = -1, - - LLVMError = -101, - UnexpectedError = -111 -} - -/// JitContext struct declaration. -pub enum JitContext {} - /// Safe handle for jit context. pub struct ContextHandle { context: *mut JitContext, @@ -83,7 +56,7 @@ pub struct ContextHandle { impl ContextHandle { /// Creates new context handle. - pub fn new(mut data_handle: RuntimeDataHandle, mut env: Env) -> Self { + pub fn new(mut data_handle: RuntimeDataHandle, mut env: EnvHandle) -> Self { let context = unsafe { evmjit_create_context(data_handle.mut_runtime_data(), &mut env) }; ContextHandle { context: context, @@ -104,29 +77,29 @@ impl Drop for ContextHandle { } /// Component oriented wrapper around jit env c interface. -pub trait JitEnv { +pub trait Env { fn sload(&mut self); } -/// C abi compatible wrapper for JitEnvTrait implementers. -pub struct Env { - env_impl: Option> +/// C abi compatible wrapper for jit env implementers. +pub struct EnvHandle { + env_impl: Option> } -impl Env { +impl EnvHandle { /// Creates new environment wrapper for given implementation - pub fn new(env_impl: T) -> Self where T: JitEnv + 'static { - Env { env_impl: Some(Box::new(env_impl)) } + pub fn new(env_impl: T) -> Self where T: Env + 'static { + EnvHandle { env_impl: Some(Box::new(env_impl)) } } /// Creates empty environment. /// It can be used to for any operations. pub fn empty() -> Self { - Env { env_impl: None } + EnvHandle { env_impl: None } } } -impl JitEnv for Env { +impl Env for EnvHandle { fn sload(&mut self) { match self.env_impl { Some(ref mut env) => env.sload(), @@ -135,93 +108,143 @@ impl JitEnv for Env { } } -#[no_mangle] -pub unsafe extern fn env_sload(env: *mut Env, _index: *const JitI256, _value: *const JitI256) { - let env = &mut *env; - env.sload(); -} +/// ffi functions +pub mod ffi { + use super::*; + use libc; -#[no_mangle] -pub extern fn env_sstore(_env: *mut Env, _index: *const JitI256, _value: *const JitI256) { - unimplemented!() -} + /// Jit context struct declaration. + pub enum JitContext {} -#[no_mangle] -pub extern fn env_balance(_env: *mut Env, _address: *const JitI256, _value: *const JitI256) { - unimplemented!() -} + #[repr(C)] + #[derive(Debug, Eq, PartialEq)] + /// Jit context execution return code. + pub enum JitReturnCode { + Stop = 0, + Return = 1, + Suicide = 2, -#[no_mangle] -pub extern fn env_blockhash(_env: *mut Env, _number: *const JitI256, _hash: *const JitI256) { - unimplemented!() -} + OutOfGas = -1, -#[no_mangle] -pub extern fn env_create(_env: *mut Env, - _io_gas: *const u64, - _endowment: *const JitI256, - _init_beg: *const u8, - _init_size: *const u64, - _address: *const JitI256) { - unimplemented!() -} + LLVMError = -101, + UnexpectedError = -111 + } -#[no_mangle] -pub extern fn env_call(_env: *mut Env, - _io_gas: *const u64, - _call_gas: *const u64, - _receive_address: *const JitI256, - _value: *const JitI256, - _in_beg: *const u8, - _in_size: *const u64, - _out_beg: *const u8, - _out_size: *const u64, - _code_address: JitI256) { - unimplemented!() -} + #[repr(C)] + /// Signed 256 bit integer. + pub struct JitI256 { + pub words: [u64; 4] + } -#[no_mangle] -pub extern fn env_sha3(_begin: *const u8, _size: *const u64, _hash: *const JitI256) { - unimplemented!() -} + #[repr(C)] + /// Jit runtime data. + pub struct JitRuntimeData { + pub gas: i64, + pub gas_price: i64, + pub call_data: *const libc::c_char, + pub call_data_size: u64, + pub address: JitI256, + pub caller: JitI256, + pub origin: JitI256, + pub call_value: JitI256, + pub coinbase: JitI256, + pub difficulty: JitI256, + pub gas_limit: JitI256, + pub number: u64, + pub timestamp: i64, + pub code: *const libc::c_char, + pub code_size: u64, + pub code_hash: JitI256 + } -#[no_mangle] -pub extern fn env_extcode(_env: *mut Env, _address: *const JitI256, _size: *const u64) { - unimplemented!() -} + #[no_mangle] + pub unsafe extern fn env_sload(env: *mut EnvHandle, _index: *const JitI256, _value: *const JitI256) { + let env = &mut *env; + env.sload(); + } -#[no_mangle] -pub extern fn env_log(_env: *mut Env, - _beg: *const u8, - _size: *const u64, - _topic1: *const JitI256, - _topic2: *const JitI256, - _topic3: *const JitI256, - _topic4: *const JitI256) { - unimplemented!() -} + #[no_mangle] + pub extern fn env_sstore(_env: *mut EnvHandle, _index: *const JitI256, _value: *const JitI256) { + unimplemented!() + } + + #[no_mangle] + pub extern fn env_balance(_env: *mut EnvHandle, _address: *const JitI256, _value: *const JitI256) { + unimplemented!() + } + + #[no_mangle] + pub extern fn env_blockhash(_env: *mut EnvHandle, _number: *const JitI256, _hash: *const JitI256) { + unimplemented!() + } + + #[no_mangle] + pub extern fn env_create(_env: *mut EnvHandle, + _io_gas: *const u64, + _endowment: *const JitI256, + _init_beg: *const u8, + _init_size: *const u64, + _address: *const JitI256) { + unimplemented!() + } + + #[no_mangle] + pub extern fn env_call(_env: *mut EnvHandle, + _io_gas: *const u64, + _call_gas: *const u64, + _receive_address: *const JitI256, + _value: *const JitI256, + _in_beg: *const u8, + _in_size: *const u64, + _out_beg: *const u8, + _out_size: *const u64, + _code_address: JitI256) { + unimplemented!() + } + + #[no_mangle] + pub extern fn env_sha3(_begin: *const u8, _size: *const u64, _hash: *const JitI256) { + unimplemented!() + } + + #[no_mangle] + pub extern fn env_extcode(_env: *mut EnvHandle, _address: *const JitI256, _size: *const u64) { + unimplemented!() + } + + #[no_mangle] + pub extern fn env_log(_env: *mut EnvHandle, + _beg: *const u8, + _size: *const u64, + _topic1: *const JitI256, + _topic2: *const JitI256, + _topic3: *const JitI256, + _topic4: *const JitI256) { + unimplemented!() + } -#[link(name="evmjit")] -extern "C" { - pub fn evmjit_create_runtime_data() -> *mut JitRuntimeData; - pub fn evmjit_destroy_runtime_data(data: *mut JitRuntimeData); - pub fn evmjit_destroy_context(context: *mut JitContext); - pub fn evmjit_exec(context: *mut JitContext) -> JitReturnCode; -} + #[link(name="evmjit")] + extern "C" { + pub fn evmjit_create_runtime_data() -> *mut JitRuntimeData; + pub fn evmjit_destroy_runtime_data(data: *mut JitRuntimeData); + pub fn evmjit_destroy_context(context: *mut JitContext); + pub fn evmjit_exec(context: *mut JitContext) -> JitReturnCode; + } -#[link(name="evmjit")] -// Env does not have to by a C type -#[allow(improper_ctypes)] -extern "C" { - pub fn evmjit_create_context(data: *mut JitRuntimeData, env: *mut Env) -> *mut JitContext; + #[link(name="evmjit")] + // EnvHandle does not have to by a C type + #[allow(improper_ctypes)] + extern "C" { + pub fn evmjit_create_context(data: *mut JitRuntimeData, env: *mut EnvHandle) -> *mut JitContext; + } } #[test] fn ffi_test() { unsafe { let data = evmjit_create_runtime_data(); - let context = evmjit_create_context(data, &mut Env::empty()); + let context = evmjit_create_context(data, &mut EnvHandle::empty()); let code = evmjit_exec(context); assert_eq!(code, JitReturnCode::Stop); @@ -233,6 +256,6 @@ fn ffi_test() { #[test] fn handle_test() { - let mut context = ContextHandle::new(RuntimeDataHandle::new(), Env::empty()); - assert_eq!(context.exec(), JitReturnCode::Stop); + let mut context = ContextHandle::new(RuntimeDataHandle::new(), EnvHandle::empty()); + assert_eq!(context.exec(), ReturnCode::Stop); } From 963d967a46d565caef65acd8f8c689f3fcbf8b34 Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 22 Dec 2015 17:13:03 +0100 Subject: [PATCH 4/7] sstore && sload --- rust-evmjit/src/lib.rs | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/rust-evmjit/src/lib.rs b/rust-evmjit/src/lib.rs index ae641e045..304cecaf9 100644 --- a/rust-evmjit/src/lib.rs +++ b/rust-evmjit/src/lib.rs @@ -78,7 +78,8 @@ impl Drop for ContextHandle { /// Component oriented wrapper around jit env c interface. pub trait Env { - fn sload(&mut self); + fn sload(&self, index: *const JitI256, out_value: *mut JitI256); + fn sstore(&mut self, index: *const JitI256, value: *const JitI256); } /// C abi compatible wrapper for jit env implementers. @@ -100,12 +101,20 @@ impl EnvHandle { } impl Env for EnvHandle { - fn sload(&mut self) { + fn sload(&self, index: *const JitI256, out_value: *mut JitI256) { match self.env_impl { - Some(ref mut env) => env.sload(), + Some(ref env) => env.sload(index, out_value), None => { panic!(); } } } + + fn sstore(&mut self, index: *const JitI256, value: *const JitI256) { + match self.env_impl { + Some(ref mut env) => env.sstore(index, value), + None => { panic!(); } + } + } + } /// ffi functions @@ -158,14 +167,15 @@ pub mod ffi { } #[no_mangle] - pub unsafe extern fn env_sload(env: *mut EnvHandle, _index: *const JitI256, _value: *const JitI256) { - let env = &mut *env; - env.sload(); + pub unsafe extern fn env_sload(env: *mut EnvHandle, index: *const JitI256, out_value: *mut JitI256) { + let env = &*env; + env.sload(index, out_value); } #[no_mangle] - pub extern fn env_sstore(_env: *mut EnvHandle, _index: *const JitI256, _value: *const JitI256) { - unimplemented!() + pub unsafe extern fn env_sstore(env: *mut EnvHandle, index: *const JitI256, value: *const JitI256) { + let env = &mut *env; + env.sstore(index, value); } #[no_mangle] From 6697edc0edd6c8d56dabe4ef47b9a0fa9c4a177b Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 22 Dec 2015 17:37:52 +0100 Subject: [PATCH 5/7] evmhandle deref && deref mut, mapped balance && blockhash --- rust-evmjit/src/lib.rs | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/rust-evmjit/src/lib.rs b/rust-evmjit/src/lib.rs index 304cecaf9..68067d493 100644 --- a/rust-evmjit/src/lib.rs +++ b/rust-evmjit/src/lib.rs @@ -14,6 +14,7 @@ //! ``` extern crate libc; +use std::ops::{Deref, DerefMut}; use self::ffi::*; pub use self::ffi::JitReturnCode as ReturnCode; @@ -80,6 +81,8 @@ impl Drop for ContextHandle { pub trait Env { fn sload(&self, index: *const JitI256, out_value: *mut JitI256); fn sstore(&mut self, index: *const JitI256, value: *const JitI256); + fn balance(&self, address: *const JitI256, out_value: *mut JitI256); + fn blockhash(&self, number: *const JitI256, out_hash: *mut JitI256); } /// C abi compatible wrapper for jit env implementers. @@ -100,21 +103,24 @@ impl EnvHandle { } } -impl Env for EnvHandle { - fn sload(&self, index: *const JitI256, out_value: *mut JitI256) { +impl Deref for EnvHandle { + type Target = Box; + + fn deref(&self) -> &Self::Target { match self.env_impl { - Some(ref env) => env.sload(index, out_value), + Some(ref env) => env, None => { panic!(); } } } +} - fn sstore(&mut self, index: *const JitI256, value: *const JitI256) { +impl DerefMut for EnvHandle { + fn deref_mut(&mut self) -> &mut Self::Target { match self.env_impl { - Some(ref mut env) => env.sstore(index, value), + Some(ref mut env) => env, None => { panic!(); } } } - } /// ffi functions @@ -167,7 +173,7 @@ pub mod ffi { } #[no_mangle] - pub unsafe extern fn env_sload(env: *mut EnvHandle, index: *const JitI256, out_value: *mut JitI256) { + pub unsafe extern fn env_sload(env: *const EnvHandle, index: *const JitI256, out_value: *mut JitI256) { let env = &*env; env.sload(index, out_value); } @@ -179,13 +185,15 @@ pub mod ffi { } #[no_mangle] - pub extern fn env_balance(_env: *mut EnvHandle, _address: *const JitI256, _value: *const JitI256) { - unimplemented!() + pub unsafe extern fn env_balance(env: *const EnvHandle, address: *const JitI256, out_value: *mut JitI256) { + let env = &*env; + env.balance(address, out_value); } #[no_mangle] - pub extern fn env_blockhash(_env: *mut EnvHandle, _number: *const JitI256, _hash: *const JitI256) { - unimplemented!() + pub unsafe extern fn env_blockhash(env: *const EnvHandle, number: *const JitI256, out_hash: *mut JitI256) { + let env = &*env; + env.blockhash(number, out_hash); } #[no_mangle] From 4d6c5762ff56624769d93129d213fd6fd0b868f0 Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 22 Dec 2015 18:00:47 +0100 Subject: [PATCH 6/7] env ffi --- rust-evmjit/src/lib.rs | 79 +++++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 28 deletions(-) diff --git a/rust-evmjit/src/lib.rs b/rust-evmjit/src/lib.rs index 68067d493..42d30ec3f 100644 --- a/rust-evmjit/src/lib.rs +++ b/rust-evmjit/src/lib.rs @@ -83,6 +83,26 @@ pub trait Env { fn sstore(&mut self, index: *const JitI256, value: *const JitI256); fn balance(&self, address: *const JitI256, out_value: *mut JitI256); fn blockhash(&self, number: *const JitI256, out_hash: *mut JitI256); + + fn create(&mut self, + io_gas: *mut u64, + endowment: *const JitI256, + init_beg: *const u8, + init_size: *const u64, + address: *mut JitI256); + + fn call(&mut self, + io_gas: *mut u64, + call_gas: *const u64, + receive_address: *const JitI256, + value: *const JitI256, + in_beg: *const u8, + in_size: *const u64, + out_beg: *mut u8, + out_size: *mut u64, + code_address: JitI256) -> bool; + + fn extcode(&self, address: *const JitI256, size: *mut u64) -> *const u8; } /// C abi compatible wrapper for jit env implementers. @@ -197,41 +217,44 @@ pub mod ffi { } #[no_mangle] - pub extern fn env_create(_env: *mut EnvHandle, - _io_gas: *const u64, - _endowment: *const JitI256, - _init_beg: *const u8, - _init_size: *const u64, - _address: *const JitI256) { + pub unsafe extern fn env_create(env: *mut EnvHandle, + io_gas: *mut u64, + endowment: *const JitI256, + init_beg: *const u8, + init_size: *const u64, + address: *mut JitI256) { + let env = &mut *env; + env.create(io_gas, endowment, init_beg, init_size, address); + } + + #[no_mangle] + pub unsafe extern fn env_call(env: *mut EnvHandle, + io_gas: *mut u64, + call_gas: *const u64, + receive_address: *const JitI256, + value: *const JitI256, + in_beg: *const u8, + in_size: *const u64, + out_beg: *mut u8, + out_size: *mut u64, + code_address: JitI256) -> bool { + let env = &mut *env; + env.call(io_gas, call_gas, receive_address, value, in_beg, in_size, out_beg, out_size, code_address) + } + + #[no_mangle] + pub unsafe extern fn env_sha3(_begin: *const u8, _size: *const u64, _out_hash: *const JitI256) { unimplemented!() } #[no_mangle] - pub extern fn env_call(_env: *mut EnvHandle, - _io_gas: *const u64, - _call_gas: *const u64, - _receive_address: *const JitI256, - _value: *const JitI256, - _in_beg: *const u8, - _in_size: *const u64, - _out_beg: *const u8, - _out_size: *const u64, - _code_address: JitI256) { - unimplemented!() + pub unsafe extern fn env_extcode(env: *const EnvHandle, address: *const JitI256, size: *mut u64) -> *const u8 { + let env = &*env; + env.extcode(address, size) } #[no_mangle] - pub extern fn env_sha3(_begin: *const u8, _size: *const u64, _hash: *const JitI256) { - unimplemented!() - } - - #[no_mangle] - pub extern fn env_extcode(_env: *mut EnvHandle, _address: *const JitI256, _size: *const u64) { - unimplemented!() - } - - #[no_mangle] - pub extern fn env_log(_env: *mut EnvHandle, + pub unsafe extern fn env_log(_env: *mut EnvHandle, _beg: *const u8, _size: *const u64, _topic1: *const JitI256, From ee8c903b0b02efec8ff5cc2abbf0fc8ad4c366a2 Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 22 Dec 2015 20:05:14 +0100 Subject: [PATCH 7/7] sha3 && log --- rust-evmjit/Cargo.toml | 1 + rust-evmjit/src/lib.rs | 43 ++++++++++++++++++++++++++++++------------ 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/rust-evmjit/Cargo.toml b/rust-evmjit/Cargo.toml index 54c4437f4..4fabe4f97 100644 --- a/rust-evmjit/Cargo.toml +++ b/rust-evmjit/Cargo.toml @@ -5,3 +5,4 @@ authors = ["debris "] [dependencies] libc = "0.2.2" +tiny-keccak = "1.0" diff --git a/rust-evmjit/src/lib.rs b/rust-evmjit/src/lib.rs index 42d30ec3f..8958f2b2f 100644 --- a/rust-evmjit/src/lib.rs +++ b/rust-evmjit/src/lib.rs @@ -1,4 +1,4 @@ -//! Bare rust wrapper around evmjit +//! Bare rust wrapper around evmjit. //! //! Requires latest version of Ethereum EVM JIT. https://github.com/debris/evmjit //! @@ -14,6 +14,8 @@ //! ``` extern crate libc; +extern crate tiny_keccak; + use std::ops::{Deref, DerefMut}; use self::ffi::*; @@ -102,6 +104,14 @@ pub trait Env { out_size: *mut u64, code_address: JitI256) -> bool; + fn log(&mut self, + beg: *const u8, + size: *const u64, + topic1: *const JitI256, + topic2: *const JitI256, + topic3: *const JitI256, + topic4: *const JitI256); + fn extcode(&self, address: *const JitI256, size: *mut u64) -> *const u8; } @@ -145,8 +155,10 @@ impl DerefMut for EnvHandle { /// ffi functions pub mod ffi { - use super::*; + use std::slice; use libc; + use tiny_keccak::Keccak; + use super::*; /// Jit context struct declaration. pub enum JitContext {} @@ -243,8 +255,14 @@ pub mod ffi { } #[no_mangle] - pub unsafe extern fn env_sha3(_begin: *const u8, _size: *const u64, _out_hash: *const JitI256) { - unimplemented!() + pub unsafe extern fn env_sha3(begin: *const u8, size: *const u64, out_hash: *mut JitI256) { + let out_hash = &mut *out_hash; + let input = slice::from_raw_parts(begin, *size as usize); + let outlen = out_hash.words.len() * 8; + let output = slice::from_raw_parts_mut(out_hash.words.as_mut_ptr() as *mut u8, outlen); + let mut sha3 = Keccak::new_sha3_256(); + sha3.update(input); + sha3.finalize(output); } #[no_mangle] @@ -254,14 +272,15 @@ pub mod ffi { } #[no_mangle] - pub unsafe extern fn env_log(_env: *mut EnvHandle, - _beg: *const u8, - _size: *const u64, - _topic1: *const JitI256, - _topic2: *const JitI256, - _topic3: *const JitI256, - _topic4: *const JitI256) { - unimplemented!() + pub unsafe extern fn env_log(env: *mut EnvHandle, + beg: *const u8, + size: *const u64, + topic1: *const JitI256, + topic2: *const JitI256, + topic3: *const JitI256, + topic4: *const JitI256) { + let env = &mut *env; + env.log(beg, size, topic1, topic2, topic3, topic4); }