diff --git a/Cargo.lock b/Cargo.lock index 2144c1719..1d8b3bce1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -256,6 +256,7 @@ dependencies = [ "ethcore-util 1.3.2", "ethjson 0.1.0", "ethstore 0.1.0", + "evmjit 1.3.0", "heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.9.4 (git+https://github.com/ethcore/hyper)", "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -538,6 +539,13 @@ dependencies = [ "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "evmjit" +version = "1.3.0" +dependencies = [ + "tiny-keccak 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fdlimit" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 939c60e98..fbeec95c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,6 +59,7 @@ ui = ["dapps", "ethcore-signer/ui"] use-precompiled-js = ["ethcore-dapps/use-precompiled-js", "ethcore-signer/use-precompiled-js"] dapps = ["ethcore-dapps"] ipc = ["ethcore/ipc"] +jit = ["ethcore/jit"] dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethcore-rpc/dev", "ethcore-dapps/dev", "ethcore-signer/dev"] json-tests = ["ethcore/json-tests"] diff --git a/ethcore/src/evm/jit.rs b/ethcore/src/evm/jit.rs index 4f43d327b..d82295234 100644 --- a/ethcore/src/evm/jit.rs +++ b/ethcore/src/evm/jit.rs @@ -18,6 +18,7 @@ use common::*; use evmjit; use evm::{self, GasLeft}; +use types::executed::CallType; /// Should be used to convert jit types to ethcore trait FromJit: Sized { @@ -77,10 +78,11 @@ impl IntoJit for U256 { 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 len = self.len(); + for i in 0..len { + let rev = len - 1 - i; let pos = rev / 8; - ret[pos] += (self.bytes()[i] as u64) << ((rev % 8) * 8); + ret[pos] += (self[i] as u64) << ((rev % 8) * 8); } evmjit::I256 { words: ret } } @@ -194,6 +196,7 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> { receive_address: *const evmjit::H256, code_address: *const evmjit::H256, transfer_value: *const evmjit::I256, + // Ignoring apparent value - it's handled correctly in executive. _apparent_value: *const evmjit::I256, in_beg: *const u8, in_size: u64, @@ -207,10 +210,12 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> { let receive_address = unsafe { Address::from_jit(&*receive_address) }; let code_address = unsafe { Address::from_jit(&*code_address) }; let transfer_value = unsafe { U256::from_jit(&*transfer_value) }; - let value = Some(transfer_value); // receive address and code address are the same in normal calls let is_callcode = receive_address != code_address; + let is_delegatecall = is_callcode && sender_address != receive_address; + + let value = if is_delegatecall { None } else { Some(transfer_value) }; if !is_callcode && !self.ext.exists(&code_address) { gas_cost = gas_cost + U256::from(self.ext.schedule().call_new_account_gas); @@ -239,6 +244,12 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> { } } + let call_type = match (is_callcode, is_delegatecall) { + (_, true) => CallType::DelegateCall, + (true, false) => CallType::CallCode, + (false, false) => CallType::Call, + }; + match self.ext.call( &call_gas, &sender_address, @@ -246,7 +257,9 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> { value, unsafe { slice::from_raw_parts(in_beg, in_size as usize) }, &code_address, - unsafe { slice::from_raw_parts_mut(out_beg, out_size as usize) }) { + unsafe { slice::from_raw_parts_mut(out_beg, out_size as usize) }, + call_type, + ) { evm::MessageCallResult::Success(gas_left) => unsafe { *io_gas = (gas + gas_left).low_u64(); true diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 97625ff98..4290d8f4d 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -102,7 +102,8 @@ extern crate rand; extern crate bit_set; extern crate lru_cache; -#[cfg(feature = "jit" )] extern crate evmjit; +#[cfg(feature = "jit" )] +extern crate evmjit; pub mod account_provider; pub mod engines;