From 353d4fbea03e504945ca8066e0820488ae4c706b Mon Sep 17 00:00:00 2001 From: debris Date: Wed, 23 Dec 2015 13:02:01 +0100 Subject: [PATCH] evm adapter init --- rust-evmjit/Cargo.toml | 1 - rust-evmjit/src/lib.rs | 22 ++++-- src/evm/env.rs | 19 +++++ src/evm/jit.rs | 153 +++++++++++++++++++++++++++++++++++++++++ src/evm/mod.rs | 5 ++ src/lib.rs | 1 + 6 files changed, 196 insertions(+), 5 deletions(-) create mode 100644 src/evm/env.rs create mode 100644 src/evm/jit.rs create mode 100644 src/evm/mod.rs diff --git a/rust-evmjit/Cargo.toml b/rust-evmjit/Cargo.toml index 4fabe4f97..d574af98f 100644 --- a/rust-evmjit/Cargo.toml +++ b/rust-evmjit/Cargo.toml @@ -4,5 +4,4 @@ version = "0.1.0" 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 8958f2b2f..5e11a27db 100644 --- a/rust-evmjit/src/lib.rs +++ b/rust-evmjit/src/lib.rs @@ -13,13 +13,13 @@ //! //! ``` -extern crate libc; extern crate tiny_keccak; use std::ops::{Deref, DerefMut}; use self::ffi::*; pub use self::ffi::JitReturnCode as ReturnCode; +pub use self::ffi::JitI256 as I256; /// Component oriented safe handle to `JitRuntimeData`. pub struct RuntimeDataHandle { @@ -51,6 +51,20 @@ impl Drop for RuntimeDataHandle { } } +impl Deref for RuntimeDataHandle { + type Target = JitRuntimeData; + + fn deref(&self) -> &Self::Target { + self.runtime_data() + } +} + +impl DerefMut for RuntimeDataHandle { + fn deref_mut(&mut self) -> &mut Self::Target { + self.mut_runtime_data() + } +} + /// Safe handle for jit context. pub struct ContextHandle { context: *mut JitContext, @@ -156,7 +170,6 @@ impl DerefMut for EnvHandle { /// ffi functions pub mod ffi { use std::slice; - use libc; use tiny_keccak::Keccak; use super::*; @@ -178,6 +191,7 @@ pub mod ffi { } #[repr(C)] + #[derive(Debug)] /// Signed 256 bit integer. pub struct JitI256 { pub words: [u64; 4] @@ -188,7 +202,7 @@ pub mod ffi { pub struct JitRuntimeData { pub gas: i64, pub gas_price: i64, - pub call_data: *const libc::c_char, + pub call_data: *const u8, pub call_data_size: u64, pub address: JitI256, pub caller: JitI256, @@ -199,7 +213,7 @@ pub mod ffi { pub gas_limit: JitI256, pub number: u64, pub timestamp: i64, - pub code: *const libc::c_char, + pub code: *const u8, pub code_size: u64, pub code_hash: JitI256 } diff --git a/src/evm/env.rs b/src/evm/env.rs new file mode 100644 index 000000000..9221b5a6c --- /dev/null +++ b/src/evm/env.rs @@ -0,0 +1,19 @@ +use util::hash::*; + +pub struct Env; + +impl Env { + pub fn new() -> Env { + Env + } + + pub fn sload(&self, _index: &H256) -> H256 { + unimplemented!(); + } + + pub fn sstore(&self, _index: &H256, _value: &H256) { + unimplemented!(); + } +} + + diff --git a/src/evm/jit.rs b/src/evm/jit.rs new file mode 100644 index 000000000..2efc5ce1c --- /dev/null +++ b/src/evm/jit.rs @@ -0,0 +1,153 @@ +use std::mem; +use evmjit; +use util::hash::*; +use util::uint::*; +use util::bytes::*; +use evm; + +/// Should be used to convert jit i256 to ethcore types +pub trait FromJit: Sized { + fn from_jit(input: &evmjit::I256) -> Self; +} + +/// Should be used to covert ethcore types to jit i256 +pub trait IntoJit { + fn into_jit(self) -> evmjit::I256; +} + +impl FromJit for U256 { + fn from_jit(input: &evmjit::I256) -> Self { + let mut res: U256 = unsafe { mem::uninitialized() }; + res.0[0] = input.words[3]; + res.0[1] = input.words[2]; + res.0[2] = input.words[1]; + res.0[3] = input.words[0]; + res + } +} + +impl FromJit for H256 { + fn from_jit(input: &evmjit::I256) -> Self { + let u = U256::from_jit(input); + H256::from(&u) + } +} + +impl IntoJit for U256 { + fn into_jit(self) -> evmjit::I256 { + let mut res: evmjit::I256 = unsafe { mem::uninitialized() }; + res.words[0] = self.0[3]; + res.words[1] = self.0[2]; + res.words[2] = self.0[1]; + res.words[3] = self.0[0]; + res + } +} + +impl IntoJit for H256 { + fn into_jit(self) -> evmjit::I256 { + let mut ret = [0; 4]; + for i in 0..self.bytes().len() { + let rev = self.bytes().len() - 1 - i; + let pos = i / 8; + ret[pos] += (self.bytes()[i] as u64) << (rev % 8) * 8; + } + evmjit::I256 { words: ret } + } +} + +pub struct EnvAdapter { + env: evm::Env +} + +impl EnvAdapter { + pub fn new() -> EnvAdapter { + EnvAdapter { + env: evm::Env::new() + } + } +} + +impl evmjit::Env for EnvAdapter { + fn sload(&self, index: *const evmjit::I256, out_value: *mut evmjit::I256) { + unsafe { + let i = H256::from_jit(&*index); + let o = self.env.sload(&i); + *out_value = o.into_jit(); + } + } + + fn sstore(&mut self, index: *const evmjit::I256, value: *const evmjit::I256) { + unsafe { + self.env.sstore(&H256::from_jit(&*index), &H256::from_jit(&*value)); + } + } + + fn balance(&self, _address: *const evmjit::I256, _out_value: *mut evmjit::I256) { + unimplemented!(); + } + + fn blockhash(&self, _number: *const evmjit::I256, _out_hash: *mut evmjit::I256) { + unimplemented!(); + } + + fn create(&mut self, + _io_gas: *mut u64, + _endowment: *const evmjit::I256, + _init_beg: *const u8, + _init_size: *const u64, + _address: *mut evmjit::I256) { + unimplemented!(); + } + + fn call(&mut self, + _io_gas: *mut u64, + _call_gas: *const u64, + _receive_address: *const evmjit::I256, + _value: *const evmjit::I256, + _in_beg: *const u8, + _in_size: *const u64, + _out_beg: *mut u8, + _out_size: *mut u64, + _code_address: evmjit::I256) -> bool { + unimplemented!(); + } + + fn log(&mut self, + _beg: *const u8, + _size: *const u64, + _topic1: *const evmjit::I256, + _topic2: *const evmjit::I256, + _topic3: *const evmjit::I256, + _topic4: *const evmjit::I256) { + unimplemented!(); + } + + fn extcode(&self, _address: *const evmjit::I256, _size: *mut u64) -> *const u8 { + unimplemented!(); + } +} + + +#[test] +fn test_to_and_from_u256() { + use std::str::FromStr; + + let u = U256::from_str("d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3").unwrap(); + let j = u.into_jit(); + let u2 = U256::from_jit(&j); + assert_eq!(u, u2); +} + +#[test] +fn test_to_and_from_h256() { + use std::str::FromStr; + + let h = H256::from_str("d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3").unwrap(); + let j = h.clone().into_jit(); + println!("jit: {:?}", j); + let h2 = H256::from_jit(&j); + assert_eq!(h, h2); +} + + diff --git a/src/evm/mod.rs b/src/evm/mod.rs new file mode 100644 index 000000000..fe429e186 --- /dev/null +++ b/src/evm/mod.rs @@ -0,0 +1,5 @@ +#[cfg(feature = "jit" )] +pub mod jit; +pub mod env; + +pub use self::env::Env; diff --git a/src/lib.rs b/src/lib.rs index 41cdc9515..89f9604cd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -104,3 +104,4 @@ pub mod genesis; pub mod views; pub mod blockchain; pub mod extras; +pub mod evm;