fixed signal 11 error

This commit is contained in:
debris 2015-12-28 22:37:15 +01:00
parent f2ae8708de
commit 4e31fe5785
5 changed files with 67 additions and 42 deletions

View File

@ -69,21 +69,19 @@ impl DerefMut for RuntimeDataHandle {
pub struct ContextHandle { pub struct ContextHandle {
context: *mut JitContext, context: *mut JitContext,
data_handle: RuntimeDataHandle, data_handle: RuntimeDataHandle,
env: EnvHandle
} }
impl ContextHandle { impl ContextHandle {
/// Creates new context handle. /// Creates new context handle.
pub fn new(data_handle: RuntimeDataHandle, env: EnvHandle) -> Self { /// This function is unsafe cause env lifetime is not considered
pub unsafe fn new(data_handle: RuntimeDataHandle, env: &mut EnvHandle) -> Self {
import_evmjit_abi(); import_evmjit_abi();
let mut handle = ContextHandle { let mut handle = ContextHandle {
context: unsafe {::std::mem::uninitialized()}, context: std::mem::uninitialized(),
data_handle: data_handle, data_handle: data_handle,
env: env
}; };
println!("env address: {:?}", &handle.env as *const _); handle.context = evmjit_create_context(handle.data_handle.mut_runtime_data(), env);
handle.context = unsafe { evmjit_create_context(handle.data_handle.mut_runtime_data(), &mut handle.env) };
handle handle
} }
@ -263,32 +261,30 @@ pub mod ffi {
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn env_sload(env: *const EnvHandle, index: *const JitI256, out_value: *mut JitI256) { pub unsafe extern "C" fn env_sload(env: *const EnvHandle, index: *const JitI256, out_value: *mut JitI256) {
println!("sload env address: {:?}", env);
let env = &*env; let env = &*env;
env.sload(index, out_value); env.sload(index, out_value);
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn env_sstore(env: *mut EnvHandle, index: *mut JitI256, value: *mut JitI256) { pub unsafe extern "C" fn env_sstore(env: *mut EnvHandle, index: *mut JitI256, value: *mut JitI256) {
println!("sstore");
let env = &mut *env; let env = &mut *env;
env.sstore(index, value); env.sstore(index, value);
} }
#[no_mangle] #[no_mangle]
pub unsafe extern fn env_balance(env: *const EnvHandle, address: *const JitI256, out_value: *mut JitI256) { pub unsafe extern "C" fn env_balance(env: *const EnvHandle, address: *const JitI256, out_value: *mut JitI256) {
let env = &*env; let env = &*env;
env.balance(address, out_value); env.balance(address, out_value);
} }
#[no_mangle] #[no_mangle]
pub unsafe extern fn env_blockhash(env: *const EnvHandle, number: *const JitI256, out_hash: *mut JitI256) { pub unsafe extern "C" fn env_blockhash(env: *const EnvHandle, number: *const JitI256, out_hash: *mut JitI256) {
let env = &*env; let env = &*env;
env.blockhash(number, out_hash); env.blockhash(number, out_hash);
} }
#[no_mangle] #[no_mangle]
pub unsafe extern fn env_create(env: *mut EnvHandle, pub unsafe extern "C" fn env_create(env: *mut EnvHandle,
io_gas: *mut u64, io_gas: *mut u64,
endowment: *const JitI256, endowment: *const JitI256,
init_beg: *const u8, init_beg: *const u8,
@ -299,7 +295,7 @@ pub mod ffi {
} }
#[no_mangle] #[no_mangle]
pub unsafe extern fn env_call(env: *mut EnvHandle, pub unsafe extern "C" fn env_call(env: *mut EnvHandle,
io_gas: *mut u64, io_gas: *mut u64,
call_gas: *const u64, call_gas: *const u64,
receive_address: *const JitI256, receive_address: *const JitI256,
@ -314,7 +310,7 @@ pub mod ffi {
} }
#[no_mangle] #[no_mangle]
pub unsafe extern fn env_sha3(begin: *const u8, size: u64, out_hash: *mut JitI256) { pub unsafe extern "C" fn env_sha3(begin: *const u8, size: u64, out_hash: *mut JitI256) {
// TODO: write tests // TODO: write tests
// it may be incorrect due to endianess // it may be incorrect due to endianess
// if it is, don't use `from_raw_parts` // if it is, don't use `from_raw_parts`
@ -328,13 +324,13 @@ pub mod ffi {
} }
#[no_mangle] #[no_mangle]
pub unsafe extern fn env_extcode(env: *const EnvHandle, address: *const JitI256, size: *mut u64) -> *const u8 { pub unsafe extern "C" fn env_extcode(env: *const EnvHandle, address: *const JitI256, size: *mut u64) -> *const u8 {
let env = &*env; let env = &*env;
env.extcode(address, size) env.extcode(address, size)
} }
#[no_mangle] #[no_mangle]
pub unsafe extern fn env_log(env: *mut EnvHandle, pub unsafe extern "C" fn env_log(env: *mut EnvHandle,
beg: *const u8, beg: *const u8,
size: *const u64, size: *const u64,
topic1: *const JitI256, topic1: *const JitI256,

View File

@ -8,13 +8,13 @@ impl Env {
} }
pub fn sload(&self, _index: &H256) -> H256 { pub fn sload(&self, _index: &H256) -> H256 {
println!("sload!"); println!("sload!: {:?}", _index);
//unimplemented!(); //unimplemented!();
H256::new() H256::new()
} }
pub fn sstore(&self, _index: &H256, _value: &H256) { pub fn sstore(&self, _index: &H256, _value: &H256) {
println!("sstore!"); println!("sstore!: {:?} , {:?}", _index, _value);
//unimplemented!(); //unimplemented!();
} }

16
src/evm/evm.rs Normal file
View File

@ -0,0 +1,16 @@
//! EVM interface
use evm::{RuntimeData, Env};
#[derive(Debug, Eq, PartialEq)]
pub enum ReturnCode {
Stop,
Return,
Suicide,
OutOfGas,
InternalError
}
pub trait Evm {
fn exec(data: RuntimeData, env: &mut Env) -> ReturnCode;
}

View File

@ -7,12 +7,12 @@ use util::sha3::*;
use evm; use evm;
/// Should be used to convert jit types to ethcore /// Should be used to convert jit types to ethcore
pub trait FromJit<T>: Sized { trait FromJit<T>: Sized {
fn from_jit(input: T) -> Self; fn from_jit(input: T) -> Self;
} }
/// Should be used to covert ethcore types to jit /// Should be used to covert ethcore types to jit
pub trait IntoJit<T> { trait IntoJit<T> {
fn into_jit(self) -> T; fn into_jit(self) -> T;
} }
@ -88,19 +88,19 @@ impl IntoJit<evmjit::RuntimeDataHandle> for evm::RuntimeData {
} }
} }
pub struct EnvAdapter { struct EnvAdapter<'a> {
env: evm::Env env: &'a mut evm::Env
} }
impl EnvAdapter { impl<'a> EnvAdapter<'a> {
pub fn new() -> EnvAdapter { fn new(env: &'a mut evm::Env) -> Self {
EnvAdapter { EnvAdapter {
env: evm::Env::new() env: env
} }
} }
} }
impl evmjit::Env for EnvAdapter { impl<'a> evmjit::Env for EnvAdapter<'a> {
fn sload(&self, index: *const evmjit::I256, out_value: *mut evmjit::I256) { fn sload(&self, index: *const evmjit::I256, out_value: *mut evmjit::I256) {
unsafe { unsafe {
let i = H256::from_jit(&*index); let i = H256::from_jit(&*index);
@ -160,12 +160,35 @@ impl evmjit::Env for EnvAdapter {
} }
} }
impl From<evmjit::ReturnCode> for evm::ReturnCode {
fn from(code: evmjit::ReturnCode) -> Self {
match code {
evmjit::ReturnCode::Stop => evm::ReturnCode::Stop,
evmjit::ReturnCode::Return => evm::ReturnCode::Return,
evmjit::ReturnCode::Suicide => evm::ReturnCode::Suicide,
evmjit::ReturnCode::OutOfGas => evm::ReturnCode::OutOfGas,
_ => evm::ReturnCode::InternalError
}
}
}
pub struct JitEvm;
impl evm::Evm for JitEvm {
fn exec(data: evm::RuntimeData, env: &mut evm::Env) -> 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) };
From::from(context.exec())
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::str::FromStr; use std::str::FromStr;
use util::hash::*; use util::hash::*;
use util::uint::*; use util::uint::*;
use evmjit::{ContextHandle, RuntimeDataHandle, EnvHandle, ReturnCode, ffi};
use evm::*; use evm::*;
use evm::jit::{FromJit, IntoJit}; use evm::jit::{FromJit, IntoJit};
@ -189,18 +212,9 @@ mod tests {
assert_eq!(h, h2); assert_eq!(h, h2);
} }
#[test]
fn test_env_sload() {
let env = EnvHandle::new(EnvAdapter::new());
let i = U256::from(0).into_jit();
let mut o = U256::from(0).into_jit();
unsafe {
ffi::env_sload(&env as *const _, &i as *const _, &mut o as *mut _);
}
}
#[test] #[test]
fn test_env_adapter() { fn test_env_adapter() {
let mut data = RuntimeData::new(); let mut data = RuntimeData::new();
data.coinbase = Address::from_str("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba").unwrap(); data.coinbase = Address::from_str("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba").unwrap();
data.difficulty = U256::from(0x0100); data.difficulty = U256::from(0x0100);
@ -215,11 +229,8 @@ mod tests {
data.gas_price = 0x3b9aca00; data.gas_price = 0x3b9aca00;
data.origin = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); data.origin = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
data.call_value = U256::from_str("0de0b6b3a7640000").unwrap(); data.call_value = U256::from_str("0de0b6b3a7640000").unwrap();
let env = EnvAdapter::new(); let mut env = Env::new();
let mut context = ContextHandle::new(data.into_jit(), EnvHandle::new(env)); assert_eq!(JitEvm::exec(data, &mut env), ReturnCode::Stop);
// crashes with signal 11 on env.sload
assert_eq!(context.exec(), ReturnCode::Stop);
assert!(false);
} }
} }

View File

@ -2,11 +2,13 @@
pub mod env; pub mod env;
pub mod runtime_data; pub mod runtime_data;
pub mod evm;
#[cfg(feature = "jit" )] #[cfg(feature = "jit" )]
pub mod jit; pub mod jit;
pub use self::evm::{Evm, ReturnCode};
pub use self::env::Env; pub use self::env::Env;
pub use self::runtime_data::RuntimeData; pub use self::runtime_data::RuntimeData;
#[cfg(feature = "jit" )] #[cfg(feature = "jit" )]
pub use self::jit::EnvAdapter; pub use self::jit::JitEvm;