From ec720aefa9390e03e8b9e55bb750625afb9e3678 Mon Sep 17 00:00:00 2001 From: debris Date: Thu, 7 Jan 2016 19:20:23 +0100 Subject: [PATCH] env -> ext --- rust-evmjit/src/lib.rs | 160 +++++++++++++++++-------------------- src/evm/evm.rs | 4 +- src/evm/{env.rs => ext.rs} | 8 +- src/evm/jit.rs | 104 ++++++++++++------------ src/evm/mod.rs | 4 +- 5 files changed, 132 insertions(+), 148 deletions(-) rename src/evm/{env.rs => ext.rs} (96%) diff --git a/rust-evmjit/src/lib.rs b/rust-evmjit/src/lib.rs index 2c1e9854c..1b9b63100 100644 --- a/rust-evmjit/src/lib.rs +++ b/rust-evmjit/src/lib.rs @@ -7,11 +7,32 @@ //! use evmjit::*; //! //! fn main() { -//! let mut context = ContextHandle::new(RuntimeDataHandle::new(), EnvHandle::empty()); +//! let mut context = ContextHandle::new(RuntimeDataHandle::new(), ExtHandle::empty()); //! assert_eq!(context.exec(), ReturnCode::Stop); //! } //! //! ``` +//! +//! +//! To verify that c abi is "imported" correctly, run: +//! +//! ```bash +//! nm your_executable -g | grep ext +//! ``` +//! +//! It should give the following output: +//! +//! ```bash +//! 00000001000779e0 T _ext_balance +//! 0000000100077a10 T _ext_blockhash +//! 0000000100077a90 T _ext_call +//! 0000000100077a40 T _ext_create +//! 0000000100077b50 T _ext_extcode +//! 0000000100077b80 T _ext_log +//! 0000000100077b20 T _ext_sha3 +//! 0000000100077980 T _ext_sload +//! 00000001000779b0 T _ext_sstore +//! ``` extern crate tiny_keccak; @@ -74,15 +95,14 @@ pub struct ContextHandle { impl ContextHandle { /// Creates new context handle. - /// This function is unsafe cause env lifetime is not considered - pub unsafe fn new(data_handle: RuntimeDataHandle, env: &mut EnvHandle) -> Self { - import_evmjit_abi(); + /// This function is unsafe cause ext lifetime is not considered + pub unsafe fn new(data_handle: RuntimeDataHandle, ext: &mut ExtHandle) -> Self { let mut handle = ContextHandle { context: std::mem::uninitialized(), data_handle: data_handle, }; - handle.context = evmjit_create_context(handle.data_handle.mut_runtime_data(), env); + handle.context = evmjit_create_context(handle.data_handle.mut_runtime_data(), ext); handle } @@ -98,8 +118,8 @@ impl Drop for ContextHandle { } } -/// Component oriented wrapper around jit env c interface. -pub trait Env { +/// Component oriented wrapper around jit ext c interface. +pub trait Ext { 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 JitH256, out_value: *mut JitI256); @@ -134,39 +154,39 @@ pub trait Env { fn extcode(&self, address: *const JitH256, size: *mut u64) -> *const u8; } -/// C abi compatible wrapper for jit env implementers. -pub struct EnvHandle { - env_impl: Option> +/// C abi compatible wrapper for jit ext implementers. +pub struct ExtHandle { + ext_impl: Option> } -impl EnvHandle { - /// Creates new environment wrapper for given implementation - pub fn new(env_impl: T) -> Self where T: Env + 'static { - EnvHandle { env_impl: Some(Box::new(env_impl)) } +impl ExtHandle { + /// Creates new extironment wrapper for given implementation + pub fn new(ext_impl: T) -> Self where T: Ext + 'static { + ExtHandle { ext_impl: Some(Box::new(ext_impl)) } } - /// Creates empty environment. + /// Creates empty extironment. /// It can be used to for any operations. pub fn empty() -> Self { - EnvHandle { env_impl: None } + ExtHandle { ext_impl: None } } } -impl Deref for EnvHandle { - type Target = Box; +impl Deref for ExtHandle { + type Target = Box; fn deref(&self) -> &Self::Target { - match self.env_impl { - Some(ref env) => env, + match self.ext_impl { + Some(ref ext) => ext, None => { panic!("Handle is empty!"); } } } } -impl DerefMut for EnvHandle { +impl DerefMut for ExtHandle { fn deref_mut(&mut self) -> &mut Self::Target { - match self.env_impl { - Some(ref mut env) => env, + match self.ext_impl { + Some(ref mut ext) => ext, None => { panic!("Handle is empty!"); } } } @@ -256,79 +276,43 @@ pub mod ffi { pub code_hash: JitI256 } - /// Dumb function to "import" c abi in libraries - /// which inherit from this library. - /// - /// It needs to be compiled as a part of main executable. - /// - /// To verify that c abi is "imported" correctly, run: - /// - /// ```bash - /// nm your_executable -g | grep env - /// ``` - /// - /// It should give the following output: - /// - /// ```bash - /// 00000001000779e0 T _env_balance - /// 0000000100077a10 T _env_blockhash - /// 0000000100077a90 T _env_call - /// 0000000100077a40 T _env_create - /// 0000000100077b50 T _env_extcode - /// 0000000100077b80 T _env_log - /// 0000000100077b20 T _env_sha3 - /// 0000000100077980 T _env_sload - /// 00000001000779b0 T _env_sstore - /// ``` - pub fn import_evmjit_abi() { - let _env_sload = env_sload; - let _env_sstore = env_sstore; - let _env_balance = env_balance; - let _env_blockhash = env_blockhash; - let _env_create = env_create; - let _env_call = env_call; - let _env_sha3 = env_sha3; - let _env_extcode = env_extcode; - let _env_log = env_log; + #[no_mangle] + pub unsafe extern "C" fn env_sload(ext: *const ExtHandle, index: *const JitI256, out_value: *mut JitI256) { + let ext = &*ext; + ext.sload(index, out_value); } #[no_mangle] - pub unsafe extern "C" fn env_sload(env: *const EnvHandle, index: *const JitI256, out_value: *mut JitI256) { - let env = &*env; - env.sload(index, out_value); + pub unsafe extern "C" fn env_sstore(ext: *mut ExtHandle, index: *mut JitI256, value: *mut JitI256) { + let ext = &mut *ext; + ext.sstore(index, value); } #[no_mangle] - pub unsafe extern "C" fn env_sstore(env: *mut EnvHandle, index: *mut JitI256, value: *mut JitI256) { - let env = &mut *env; - env.sstore(index, value); + pub unsafe extern "C" fn env_balance(ext: *const ExtHandle, address: *const JitH256, out_value: *mut JitI256) { + let ext = &*ext; + ext.balance(address, out_value); } #[no_mangle] - pub unsafe extern "C" fn env_balance(env: *const EnvHandle, address: *const JitH256, out_value: *mut JitI256) { - let env = &*env; - env.balance(address, out_value); + pub unsafe extern "C" fn env_blockhash(ext: *const ExtHandle, number: *const JitI256, out_hash: *mut JitH256) { + let ext = &*ext; + ext.blockhash(number, out_hash); } #[no_mangle] - pub unsafe extern "C" fn env_blockhash(env: *const EnvHandle, number: *const JitI256, out_hash: *mut JitH256) { - let env = &*env; - env.blockhash(number, out_hash); - } - - #[no_mangle] - pub unsafe extern "C" fn env_create(env: *mut EnvHandle, + pub unsafe extern "C" fn env_create(ext: *mut ExtHandle, io_gas: *mut u64, endowment: *const JitI256, init_beg: *const u8, init_size: u64, address: *mut JitH256) { - let env = &mut *env; - env.create(io_gas, endowment, init_beg, init_size, address); + let ext = &mut *ext; + ext.create(io_gas, endowment, init_beg, init_size, address); } #[no_mangle] - pub unsafe extern "C" fn env_call(env: *mut EnvHandle, + pub unsafe extern "C" fn env_call(ext: *mut ExtHandle, io_gas: *mut u64, call_gas: u64, receive_address: *const JitH256, @@ -338,8 +322,8 @@ pub mod ffi { out_beg: *mut u8, out_size: u64, code_address: *const JitH256) -> bool { - let env = &mut *env; - env.call(io_gas, call_gas, receive_address, value, in_beg, in_size, out_beg, out_size, code_address) + let ext = &mut *ext; + ext.call(io_gas, call_gas, receive_address, value, in_beg, in_size, out_beg, out_size, code_address) } #[no_mangle] @@ -354,21 +338,21 @@ pub mod ffi { } #[no_mangle] - pub unsafe extern "C" fn env_extcode(env: *const EnvHandle, address: *const JitH256, size: *mut u64) -> *const u8 { - let env = &*env; - env.extcode(address, size) + pub unsafe extern "C" fn env_extcode(ext: *const ExtHandle, address: *const JitH256, size: *mut u64) -> *const u8 { + let ext = &*ext; + ext.extcode(address, size) } #[no_mangle] - pub unsafe extern "C" fn env_log(env: *mut EnvHandle, + pub unsafe extern "C" fn env_log(ext: *mut ExtHandle, beg: *const u8, size: u64, topic1: *const JitH256, topic2: *const JitH256, topic3: *const JitH256, topic4: *const JitH256) { - let env = &mut *env; - env.log(beg, size, topic1, topic2, topic3, topic4); + let ext = &mut *ext; + ext.log(beg, size, topic1, topic2, topic3, topic4); } @@ -381,10 +365,10 @@ pub mod ffi { } #[link(name="evmjit")] - // EnvHandle does not have to by a C type + // ExtHandle 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; + pub fn evmjit_create_context(data: *mut JitRuntimeData, ext: *mut ExtHandle) -> *mut JitContext; } } @@ -392,7 +376,7 @@ pub mod ffi { fn ffi_test() { unsafe { let data = evmjit_create_runtime_data(); - let context = evmjit_create_context(data, &mut EnvHandle::empty()); + let context = evmjit_create_context(data, &mut ExtHandle::empty()); let code = evmjit_exec(context); assert_eq!(code, JitReturnCode::Stop); @@ -405,7 +389,7 @@ fn ffi_test() { #[test] fn handle_test() { unsafe { - let mut context = ContextHandle::new(RuntimeDataHandle::new(), &mut EnvHandle::empty()); + let mut context = ContextHandle::new(RuntimeDataHandle::new(), &mut ExtHandle::empty()); assert_eq!(context.exec(), ReturnCode::Stop); } } diff --git a/src/evm/evm.rs b/src/evm/evm.rs index 0cf721b65..9a9b8bc41 100644 --- a/src/evm/evm.rs +++ b/src/evm/evm.rs @@ -1,6 +1,6 @@ //! Evm interface. -use evm::{RuntimeData, Env}; +use evm::{RuntimeData, Ext}; #[derive(Debug, Eq, PartialEq)] pub enum ReturnCode { @@ -12,5 +12,5 @@ pub enum ReturnCode { } pub trait Evm { - fn exec(&self, data: RuntimeData, env: &mut Env) -> ReturnCode; + fn exec(&self, data: RuntimeData, ext: &mut Ext) -> ReturnCode; } diff --git a/src/evm/env.rs b/src/evm/ext.rs similarity index 96% rename from src/evm/env.rs rename to src/evm/ext.rs index b13ec95cf..d46378d66 100644 --- a/src/evm/env.rs +++ b/src/evm/ext.rs @@ -44,17 +44,17 @@ impl SubState { /// let mut env = Env::new(EnvInfo::new(), State::new_temp(), address); /// } /// ``` -pub struct Env { +pub struct Ext { info: EnvInfo, state: State, address: Address, substate: SubState } -impl Env { +impl Ext { /// Creates new evm environment object with backing state. - pub fn new(info: EnvInfo, state: State, address: Address) -> Env { - Env { + pub fn new(info: EnvInfo, state: State, address: Address) -> Ext { + Ext { info: info, state: state, address: address, diff --git a/src/evm/jit.rs b/src/evm/jit.rs index 93e4cf2ed..80e756bf1 100644 --- a/src/evm/jit.rs +++ b/src/evm/jit.rs @@ -119,37 +119,37 @@ impl IntoJit for evm::RuntimeData { } } -struct EnvAdapter<'a> { - env: &'a mut evm::Env +struct ExtAdapter<'a> { + ext: &'a mut evm::Ext } -impl<'a> EnvAdapter<'a> { - fn new(env: &'a mut evm::Env) -> Self { - EnvAdapter { - env: env +impl<'a> ExtAdapter<'a> { + fn new(ext: &'a mut evm::Ext) -> Self { + ExtAdapter { + ext: ext } } } -impl<'a> evmjit::Env for EnvAdapter<'a> { +impl<'a> evmjit::Ext for ExtAdapter<'a> { 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); + let o = self.ext.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)); + self.ext.sstore(H256::from_jit(&*index), H256::from_jit(&*value)); } } fn balance(&self, address: *const evmjit::H256, out_value: *mut evmjit::I256) { unsafe { let a = Address::from_jit(&*address); - let o = self.env.balance(&a); + let o = self.ext.balance(&a); *out_value = o.into_jit(); } } @@ -157,7 +157,7 @@ impl<'a> evmjit::Env for EnvAdapter<'a> { fn blockhash(&self, number: *const evmjit::I256, out_hash: *mut evmjit::H256) { unsafe { let n = U256::from_jit(&*number); - let o = self.env.blockhash(&n); + let o = self.ext.blockhash(&n); *out_hash = o.into_jit(); } } @@ -169,7 +169,7 @@ impl<'a> evmjit::Env for EnvAdapter<'a> { init_size: u64, address: *mut evmjit::H256) { unsafe { - let (addr, gas) = self.env.create(*io_gas, &U256::from_jit(&*endowment), slice::from_raw_parts(init_beg, init_size as usize)); + let (addr, gas) = self.ext.create(*io_gas, &U256::from_jit(&*endowment), slice::from_raw_parts(init_beg, init_size as usize)); *io_gas = gas; *address = addr.into_jit(); } @@ -186,7 +186,7 @@ impl<'a> evmjit::Env for EnvAdapter<'a> { out_size: u64, code_address: *const evmjit::H256) -> bool { unsafe { - let opt = self.env.call(*io_gas, + let opt = self.ext.call(*io_gas, call_gas, &Address::from_jit(&*receive_address), &U256::from_jit(&*value), @@ -232,13 +232,13 @@ impl<'a> evmjit::Env for EnvAdapter<'a> { } let bytes_ref: &[u8] = slice::from_raw_parts(beg, size as usize); - self.env.log(topics, bytes_ref.to_vec()); + self.ext.log(topics, bytes_ref.to_vec()); } } fn extcode(&self, address: *const evmjit::H256, size: *mut u64) -> *const u8 { unsafe { - let code = self.env.extcode(&Address::from_jit(&*address)); + let code = self.ext.extcode(&Address::from_jit(&*address)); *size = code.len() as u64; let ptr = code.as_ptr(); mem::forget(code); @@ -262,11 +262,11 @@ impl From for evm::ReturnCode { pub struct JitEvm; impl evm::Evm for JitEvm { - fn exec(&self, data: evm::RuntimeData, env: &mut evm::Env) -> evm::ReturnCode { + fn exec(&self, data: evm::RuntimeData, ext: &mut evm::Ext) -> evm::ReturnCode { // Dirty hack. This is unsafe, but we interact with ffi, so it's justified. - let env_adapter: EnvAdapter<'static> = unsafe { ::std::mem::transmute(EnvAdapter::new(env)) }; - let mut env_handle = evmjit::EnvHandle::new(env_adapter); - let mut context = unsafe { evmjit::ContextHandle::new(data.into_jit(), &mut env_handle) }; + let ext_adapter: ExtAdapter<'static> = unsafe { ::std::mem::transmute(ExtAdapter::new(ext)) }; + let mut ext_handle = evmjit::ExtHandle::new(ext_adapter); + let mut context = unsafe { evmjit::ContextHandle::new(data.into_jit(), &mut ext_handle) }; From::from(context.exec()) } } @@ -314,49 +314,49 @@ mod tests { } #[test] - fn test_env_add() { + fn test_ext_add() { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); let mut data = RuntimeData::new(); data.address = address.clone(); data.gas = 0x174876e800; data.code = "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055".from_hex().unwrap(); - let mut env = Env::new(EnvInfo::new(), State::new_temp(), address.clone()); + let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone()); let evm = JitEvm; - assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); - let state = env.state(); + assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); + let state = ext.state(); assert_eq!(state.storage_at(&address, &H256::new()), H256::from_str("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe").unwrap()); } #[test] - fn test_env_sha3_0() { + fn test_ext_sha3_0() { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); let mut data = RuntimeData::new(); data.address = address.clone(); data.gas = 0x174876e800; data.code = "6000600020600055".from_hex().unwrap(); - let mut env = Env::new(EnvInfo::new(), State::new_temp(), address.clone()); + let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone()); let evm = JitEvm; - assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); - let state = env.state(); + assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); + let state = ext.state(); assert_eq!(state.storage_at(&address, &H256::new()), H256::from_str("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").unwrap()); } #[test] - fn test_env_sha3_1() { + fn test_ext_sha3_1() { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); let mut data = RuntimeData::new(); data.address = address.clone(); data.gas = 0x174876e800; data.code = "6005600420600055".from_hex().unwrap(); - let mut env = Env::new(EnvInfo::new(), State::new_temp(), address.clone()); + let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone()); let evm = JitEvm; - assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); - let state = env.state(); + assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); + let state = ext.state(); assert_eq!(state.storage_at(&address, &H256::new()), H256::from_str("c41589e7559804ea4a2080dad19d876a024ccb05117835447d72ce08c1d020ec").unwrap()); } @@ -370,10 +370,10 @@ mod tests { data.gas = 0x174876e800; data.code = "32600055".from_hex().unwrap(); - let mut env = Env::new(EnvInfo::new(), State::new_temp(), address.clone()); + let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone()); let evm = JitEvm; - assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); - let state = env.state(); + assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); + let state = ext.state(); assert_eq!(Address::from(state.storage_at(&address, &H256::new())), address.clone()); } @@ -386,10 +386,10 @@ mod tests { data.gas = 0x174876e800; data.code = "33600055".from_hex().unwrap(); - let mut env = Env::new(EnvInfo::new(), State::new_temp(), address.clone()); + let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone()); let evm = JitEvm; - assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); - let state = env.state(); + assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); + let state = ext.state(); assert_eq!(Address::from(state.storage_at(&address, &H256::new())), address.clone()); } @@ -420,10 +420,10 @@ mod tests { let mut state = State::new_temp(); state.set_code(&address, address_code); state.set_code(&caller, caller_code); - let mut env = Env::new(EnvInfo::new(), state, caller.clone()); + let mut ext = Ext::new(EnvInfo::new(), state, caller.clone()); let evm = JitEvm; - assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); - let state = env.state(); + assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); + let state = ext.state(); assert_eq!(state.storage_at(&caller, &H256::new()), H256::from_str("6005600055000000000000000000000000000000000000000000000000000000").unwrap()); } @@ -439,10 +439,10 @@ mod tests { let mut state = State::new_temp(); state.add_balance(&address, &U256::from(0x10)); - let mut env = Env::new(EnvInfo::new(), state, address.clone()); + let mut ext = Ext::new(EnvInfo::new(), state, address.clone()); let evm = JitEvm; - assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); - let state = env.state(); + assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); + let state = ext.state(); assert_eq!(state.storage_at(&address, &H256::new()), H256::from(&U256::from(0x10))); } @@ -455,10 +455,10 @@ mod tests { data.gas = 0x174876e800; data.code = "60006000a0".from_hex().unwrap(); - let mut env = Env::new(EnvInfo::new(), State::new_temp(), address.clone()); + let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone()); let evm = JitEvm; - assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); - let logs = env.logs(); + assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); + let logs = ext.logs(); assert_eq!(logs.len(), 1); let log = &logs[0]; assert_eq!(log.address(), &address); @@ -483,10 +483,10 @@ mod tests { data.gas = 0x174876e800; data.code = "60ff6000533360206000a1".from_hex().unwrap(); - let mut env = Env::new(EnvInfo::new(), State::new_temp(), address.clone()); + let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone()); let evm = JitEvm; - assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); - let logs = env.logs(); + assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); + let logs = ext.logs(); assert_eq!(logs.len(), 1); let log = &logs[0]; assert_eq!(log.address(), &address); @@ -509,10 +509,10 @@ mod tests { let mut info = EnvInfo::new(); info.number = U256::one(); info.last_hashes.push(H256::from(address.clone())); - let mut env = Env::new(info, State::new_temp(), address.clone()); + let mut ext = Ext::new(info, State::new_temp(), address.clone()); let evm = JitEvm; - assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); - let state = env.state(); + assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); + let state = ext.state(); assert_eq!(state.storage_at(&address, &H256::new()), H256::from(address.clone())); } } diff --git a/src/evm/mod.rs b/src/evm/mod.rs index ba0ce3b5e..c3b6216e5 100644 --- a/src/evm/mod.rs +++ b/src/evm/mod.rs @@ -1,6 +1,6 @@ //! Ethereum virtual machine. -pub mod env; +pub mod ext; pub mod runtime_data; pub mod evm; pub mod vmfactory; @@ -10,6 +10,6 @@ pub mod executive; mod jit; pub use self::evm::{Evm, ReturnCode}; -pub use self::env::Env; +pub use self::ext::Ext; pub use self::runtime_data::RuntimeData; pub use self::logentry::LogEntry;