evmjit output data

This commit is contained in:
debris 2016-01-09 18:25:18 +01:00
parent 130b2fc46a
commit 300a9506ed
5 changed files with 36 additions and 39 deletions

View File

@ -110,6 +110,11 @@ impl ContextHandle {
pub fn exec(&mut self) -> JitReturnCode { pub fn exec(&mut self) -> JitReturnCode {
unsafe { evmjit_exec(self.context) } unsafe { evmjit_exec(self.context) }
} }
/// Returns output data.
pub fn output_data(&self) -> &[u8] {
unsafe { std::slice::from_raw_parts(self.data_handle.call_data, self.data_handle.call_data_size as usize) }
}
} }
impl Drop for ContextHandle { impl Drop for ContextHandle {

View File

@ -1,16 +1,17 @@
//! Evm interface. //! Evm interface.
use util::bytes::Bytes;
use evm::{EvmParams, Ext}; use evm::{EvmParams, Ext};
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub enum ReturnCode { pub enum EvmResult {
Stop, Stop,
Return, Return(Bytes),
Suicide, Suicide,
OutOfGas, OutOfGas,
InternalError InternalError
} }
pub trait Evm { pub trait Evm {
fn exec(&self, params: &EvmParams, ext: &mut Ext) -> ReturnCode; fn exec(&self, params: &EvmParams, ext: &mut Ext) -> EvmResult;
} }

View File

@ -8,7 +8,7 @@ use state::*;
use env_info::*; use env_info::*;
use engine::*; use engine::*;
use transaction::*; use transaction::*;
use evm::{VmFactory, Ext, LogEntry, EvmParams, ReturnCode}; use evm::{VmFactory, Ext, LogEntry, EvmParams, EvmResult};
/// Returns new address created from address and given nonce. /// Returns new address created from address and given nonce.
pub fn contract_address(address: &Address, nonce: &U256) -> Address { pub fn contract_address(address: &Address, nonce: &U256) -> Address {
@ -96,26 +96,24 @@ impl<'a> Executive<'a> {
fn create(e: &mut Executive<'a>, params: &EvmParams) -> ExecutiveResult { fn create(e: &mut Executive<'a>, params: &EvmParams) -> ExecutiveResult {
//self.state.require_or_from(&self.params.address, false, ||Account::new_contract(U256::from(0))); //self.state.require_or_from(&self.params.address, false, ||Account::new_contract(U256::from(0)));
//TODO: ensure that account at given address is created
e.state.transfer_balance(&params.sender, &params.address, &params.value); e.state.transfer_balance(&params.sender, &params.address, &params.value);
let mut ext = Externalities::new(e.state, e.info, e.engine, e.depth, params);
let code = { let code = {
let mut ext = Externalities::new(e.state, e.info, e.engine, e.depth, params);
let evm = VmFactory::create(); let evm = VmFactory::create();
evm.exec(&params, &mut ext) evm.exec(&params, &mut ext)
}; };
match code { match code {
ReturnCode::Stop => { //| ReturnCode::Return => { EvmResult::Stop => {
//println!("code: {:?}", code);
//self.state.set_code(&self.params.address, self.params.code.clone());
ExecutiveResult::Ok ExecutiveResult::Ok
}, },
ReturnCode::Return => { EvmResult::Return(output) => {
//self.state.transfer_balance(&self.params.sender, &self.params.address, &self.params.value); //e.state.set_code(&params.address, output);
//self.state.set_code(&self.params.address, self.params.code.clone());
ExecutiveResult::Ok ExecutiveResult::Ok
}, },
ReturnCode::OutOfGas => { EvmResult::OutOfGas => {
ExecutiveResult::OutOfGas ExecutiveResult::OutOfGas
}, },
err => { err => {

View File

@ -286,22 +286,10 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> {
} }
} }
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; pub struct JitEvm;
impl evm::Evm for JitEvm { impl evm::Evm for JitEvm {
fn exec(&self, params: &evm::EvmParams, ext: &mut evm::Ext) -> evm::ReturnCode { fn exec(&self, params: &evm::EvmParams, ext: &mut evm::Ext) -> evm::EvmResult {
// Dirty hack. This is unsafe, but we interact with ffi, so it's justified. // Dirty hack. This is unsafe, but we interact with ffi, so it's justified.
let ext_adapter: ExtAdapter<'static> = unsafe { ::std::mem::transmute(ExtAdapter::new(ext)) }; let ext_adapter: ExtAdapter<'static> = unsafe { ::std::mem::transmute(ExtAdapter::new(ext)) };
let mut ext_handle = evmjit::ExtHandle::new(ext_adapter); let mut ext_handle = evmjit::ExtHandle::new(ext_adapter);
@ -314,7 +302,6 @@ impl evm::Evm for JitEvm {
data.origin = params.origin.clone(); data.origin = params.origin.clone();
data.call_value = params.value; data.call_value = params.value;
data.code = params.code.clone(); data.code = params.code.clone();
println!("params.address: {:?}, params.code: {:?}", params.address, params.code);
// TODO: // TODO:
data.coinbase = Address::new(); data.coinbase = Address::new();
@ -324,7 +311,13 @@ impl evm::Evm for JitEvm {
data.timestamp = 0; data.timestamp = 0;
let mut context = unsafe { evmjit::ContextHandle::new(data.into_jit(), &mut ext_handle) }; let mut context = unsafe { evmjit::ContextHandle::new(data.into_jit(), &mut ext_handle) };
From::from(context.exec()) match context.exec() {
evmjit::ReturnCode::Stop => evm::EvmResult::Stop,
evmjit::ReturnCode::Return => evm::EvmResult::Return(context.output_data().to_vec()),
evmjit::ReturnCode::Suicide => evm::EvmResult::Suicide,
evmjit::ReturnCode::OutOfGas => evm::EvmResult::OutOfGas,
_ => evm::EvmResult::InternalError
}
} }
} }
@ -406,7 +399,7 @@ mod tests {
{ {
let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params); let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params);
let evm = JitEvm; let evm = JitEvm;
assert_eq!(evm.exec(&params, &mut ext), ReturnCode::Stop); assert_eq!(evm.exec(&params, &mut ext), EvmResult::Stop);
} }
assert_eq!(state.storage_at(&address, &H256::new()), assert_eq!(state.storage_at(&address, &H256::new()),
@ -428,7 +421,7 @@ mod tests {
{ {
let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params); let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params);
let evm = JitEvm; let evm = JitEvm;
assert_eq!(evm.exec(&params, &mut ext), ReturnCode::Stop); assert_eq!(evm.exec(&params, &mut ext), EvmResult::Stop);
} }
assert_eq!(state.storage_at(&address, &H256::new()), assert_eq!(state.storage_at(&address, &H256::new()),
@ -450,7 +443,7 @@ mod tests {
{ {
let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params); let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params);
let evm = JitEvm; let evm = JitEvm;
assert_eq!(evm.exec(&params, &mut ext), ReturnCode::Stop); assert_eq!(evm.exec(&params, &mut ext), EvmResult::Stop);
} }
assert_eq!(state.storage_at(&address, &H256::new()), assert_eq!(state.storage_at(&address, &H256::new()),
@ -473,7 +466,7 @@ mod tests {
{ {
let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params); let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params);
let evm = JitEvm; let evm = JitEvm;
assert_eq!(evm.exec(&params, &mut ext), ReturnCode::Stop); assert_eq!(evm.exec(&params, &mut ext), EvmResult::Stop);
} }
assert_eq!(Address::from(state.storage_at(&address, &H256::new())), address.clone()); assert_eq!(Address::from(state.storage_at(&address, &H256::new())), address.clone());
@ -496,7 +489,7 @@ mod tests {
{ {
let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params); let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params);
let evm = JitEvm; let evm = JitEvm;
assert_eq!(evm.exec(&params, &mut ext), ReturnCode::Stop); assert_eq!(evm.exec(&params, &mut ext), EvmResult::Stop);
} }
assert_eq!(Address::from(state.storage_at(&address, &H256::new())), address.clone()); assert_eq!(Address::from(state.storage_at(&address, &H256::new())), address.clone());
@ -535,7 +528,7 @@ mod tests {
{ {
let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params); let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params);
let evm = JitEvm; let evm = JitEvm;
assert_eq!(evm.exec(&params, &mut ext), ReturnCode::Stop); assert_eq!(evm.exec(&params, &mut ext), EvmResult::Stop);
} }
assert_eq!(state.storage_at(&address, &H256::new()), assert_eq!(state.storage_at(&address, &H256::new()),
@ -559,7 +552,7 @@ mod tests {
{ {
let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params); let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params);
let evm = JitEvm; let evm = JitEvm;
assert_eq!(evm.exec(&params, &mut ext), ReturnCode::Stop); assert_eq!(evm.exec(&params, &mut ext), EvmResult::Stop);
} }
assert_eq!(state.storage_at(&address, &H256::new()), H256::from(&U256::from(0x10))); assert_eq!(state.storage_at(&address, &H256::new()), H256::from(&U256::from(0x10)));
@ -578,7 +571,7 @@ mod tests {
let engine = TestEngine::new(); let engine = TestEngine::new();
let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params); let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params);
let evm = JitEvm; let evm = JitEvm;
assert_eq!(evm.exec(&params, &mut ext), ReturnCode::Stop); assert_eq!(evm.exec(&params, &mut ext), EvmResult::Stop);
let logs = ext.logs(); let logs = ext.logs();
assert_eq!(logs.len(), 1); assert_eq!(logs.len(), 1);
let log = &logs[0]; let log = &logs[0];
@ -609,7 +602,7 @@ mod tests {
let engine = TestEngine::new(); let engine = TestEngine::new();
let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params); let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params);
let evm = JitEvm; let evm = JitEvm;
assert_eq!(evm.exec(&params, &mut ext), ReturnCode::Stop); assert_eq!(evm.exec(&params, &mut ext), EvmResult::Stop);
let logs = ext.logs(); let logs = ext.logs();
assert_eq!(logs.len(), 1); assert_eq!(logs.len(), 1);
let log = &logs[0]; let log = &logs[0];
@ -638,7 +631,7 @@ mod tests {
{ {
let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params); let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params);
let evm = JitEvm; let evm = JitEvm;
assert_eq!(evm.exec(&params, &mut ext), ReturnCode::Stop); assert_eq!(evm.exec(&params, &mut ext), EvmResult::Stop);
} }
assert_eq!(state.storage_at(&address, &H256::new()), H256::from(address.clone())); assert_eq!(state.storage_at(&address, &H256::new()), H256::from(address.clone()));
@ -662,7 +655,7 @@ mod tests {
{ {
let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params); let mut ext = Externalities::new(&mut state, &info, &engine, 0, &params);
let evm = JitEvm; let evm = JitEvm;
assert_eq!(evm.exec(&params, &mut ext), ReturnCode::Stop); assert_eq!(evm.exec(&params, &mut ext), EvmResult::Stop);
} }
assert_eq!(state.storage_at(&address, &H256::new()), H256::from_str("23ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff23").unwrap()); assert_eq!(state.storage_at(&address, &H256::new()), H256::from_str("23ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff23").unwrap());

View File

@ -9,7 +9,7 @@ pub mod params;
#[cfg(feature = "jit" )] #[cfg(feature = "jit" )]
mod jit; mod jit;
pub use self::evm::{Evm, ReturnCode}; pub use self::evm::{Evm, EvmResult};
pub use self::ext::{Ext}; pub use self::ext::{Ext};
pub use self::logentry::LogEntry; pub use self::logentry::LogEntry;
pub use self::vmfactory::VmFactory; pub use self::vmfactory::VmFactory;