Parametrizing evm::Factory
This commit is contained in:
parent
eebcd0f35b
commit
81720d6617
@ -2,24 +2,63 @@
|
|||||||
|
|
||||||
use evm::Evm;
|
use evm::Evm;
|
||||||
|
|
||||||
|
pub enum VMType {
|
||||||
|
Jit,
|
||||||
|
Interpreter
|
||||||
|
}
|
||||||
|
|
||||||
/// Evm factory. Creates appropriate Evm.
|
/// Evm factory. Creates appropriate Evm.
|
||||||
pub struct Factory;
|
pub struct Factory {
|
||||||
|
evm : VMType
|
||||||
|
}
|
||||||
|
|
||||||
impl Factory {
|
impl Factory {
|
||||||
/// Returns jit vm
|
|
||||||
|
pub fn create(&self) -> Box<Evm> {
|
||||||
|
match self.evm {
|
||||||
|
VMType::Jit => {
|
||||||
|
Factory::jit()
|
||||||
|
},
|
||||||
|
VMType::Interpreter => {
|
||||||
|
Box::new(super::interpreter::Interpreter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(evm: VMType) -> Factory {
|
||||||
|
Factory {
|
||||||
|
evm: evm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "jit")]
|
#[cfg(feature = "jit")]
|
||||||
pub fn create() -> Box<Evm> {
|
fn jit() -> Box<Evm> {
|
||||||
Box::new(super::jit::JitEvm)
|
Box::new(super::jit::JitEvm)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns native rust evm
|
|
||||||
#[cfg(not(feature = "jit"))]
|
#[cfg(not(feature = "jit"))]
|
||||||
pub fn create() -> Box<Evm> {
|
fn jit() -> Box<Evm> {
|
||||||
Box::new(super::interpreter::Interpreter)
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns jitvm factory
|
||||||
|
#[cfg(feature = "jit")]
|
||||||
|
pub fn default() -> Factory {
|
||||||
|
Factory {
|
||||||
|
evm: VMType::Jit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns native rust evm factory
|
||||||
|
#[cfg(not(feature = "jit"))]
|
||||||
|
pub fn default() -> Factory {
|
||||||
|
Factory {
|
||||||
|
evm: VMType::Interpreter
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_create_vm() {
|
fn test_create_vm() {
|
||||||
let _vm = Factory::create();
|
let _vm = Factory::default().create();
|
||||||
}
|
}
|
||||||
|
@ -127,11 +127,11 @@ macro_rules! evm_test(
|
|||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "jit")]
|
#[cfg(feature = "jit")]
|
||||||
fn $name_jit() {
|
fn $name_jit() {
|
||||||
$name_test(Box::new(super::jit::JitEvm));
|
$name_test(super::Factory::new(super::factory::VMType::Jit).create());
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn $name_int() {
|
fn $name_int() {
|
||||||
$name_test(Box::new(super::interpreter::Interpreter));
|
$name_test(super::Factory::new(super::factory::VMType::Interpreter).create());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -74,27 +74,29 @@ pub struct Executive<'a> {
|
|||||||
state: &'a mut State,
|
state: &'a mut State,
|
||||||
info: &'a EnvInfo,
|
info: &'a EnvInfo,
|
||||||
engine: &'a Engine,
|
engine: &'a Engine,
|
||||||
|
factory: &'a Factory,
|
||||||
depth: usize
|
depth: usize
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Executive<'a> {
|
impl<'a> Executive<'a> {
|
||||||
/// Basic constructor.
|
/// Basic constructor.
|
||||||
pub fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine) -> Self {
|
pub fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, factory: &'a Factory) -> Self {
|
||||||
Executive::new_with_depth(state, info, engine, 0)
|
Executive::new_with_depth(state, info, engine, factory, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Populates executive from parent properties. Increments executive depth.
|
/// Populates executive from parent properties. Increments executive depth.
|
||||||
fn from_parent(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, depth: usize) -> Self {
|
fn from_parent(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, factory: &'a Factory, depth: usize) -> Self {
|
||||||
Executive::new_with_depth(state, info, engine, depth + 1)
|
Executive::new_with_depth(state, info, engine, factory, depth + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper constructor. Should be used to create `Executive` with desired depth.
|
/// Helper constructor. Should be used to create `Executive` with desired depth.
|
||||||
/// Private.
|
/// Private.
|
||||||
fn new_with_depth(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, depth: usize) -> Self {
|
fn new_with_depth(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, factory: &'a Factory, depth: usize) -> Self {
|
||||||
Executive {
|
Executive {
|
||||||
state: state,
|
state: state,
|
||||||
info: info,
|
info: info,
|
||||||
engine: engine,
|
engine: engine,
|
||||||
|
factory: factory,
|
||||||
depth: depth
|
depth: depth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -191,8 +193,7 @@ impl<'a> Executive<'a> {
|
|||||||
} else if params.code.len() > 0 {
|
} else if params.code.len() > 0 {
|
||||||
// if destination is a contract, do normal message call
|
// if destination is a contract, do normal message call
|
||||||
let mut ext = Externalities::from_executive(self, params, substate, OutputPolicy::Return(output));
|
let mut ext = Externalities::from_executive(self, params, substate, OutputPolicy::Return(output));
|
||||||
let evm = Factory::create();
|
self.factory.create().exec(¶ms, &mut ext)
|
||||||
evm.exec(¶ms, &mut ext)
|
|
||||||
} else {
|
} else {
|
||||||
// otherwise, nothing
|
// otherwise, nothing
|
||||||
Ok(params.gas)
|
Ok(params.gas)
|
||||||
@ -209,8 +210,7 @@ impl<'a> Executive<'a> {
|
|||||||
self.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value);
|
self.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value);
|
||||||
|
|
||||||
let mut ext = Externalities::from_executive(self, params, substate, OutputPolicy::InitContract);
|
let mut ext = Externalities::from_executive(self, params, substate, OutputPolicy::InitContract);
|
||||||
let evm = Factory::create();
|
self.factory.create().exec(¶ms, &mut ext)
|
||||||
evm.exec(¶ms, &mut ext)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finalizes the transaction (does refunds and suicides).
|
/// Finalizes the transaction (does refunds and suicides).
|
||||||
@ -290,6 +290,7 @@ pub struct Externalities<'a> {
|
|||||||
state: &'a mut State,
|
state: &'a mut State,
|
||||||
info: &'a EnvInfo,
|
info: &'a EnvInfo,
|
||||||
engine: &'a Engine,
|
engine: &'a Engine,
|
||||||
|
factory: &'a Factory,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub params: &'a ActionParams,
|
pub params: &'a ActionParams,
|
||||||
@ -304,7 +305,8 @@ impl<'a> Externalities<'a> {
|
|||||||
/// Basic `Externalities` constructor.
|
/// Basic `Externalities` constructor.
|
||||||
pub fn new(state: &'a mut State,
|
pub fn new(state: &'a mut State,
|
||||||
info: &'a EnvInfo,
|
info: &'a EnvInfo,
|
||||||
engine: &'a Engine,
|
engine: &'a Engine,
|
||||||
|
factory: &'a Factory,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
params: &'a ActionParams,
|
params: &'a ActionParams,
|
||||||
substate: &'a mut Substate,
|
substate: &'a mut Substate,
|
||||||
@ -313,6 +315,7 @@ impl<'a> Externalities<'a> {
|
|||||||
state: state,
|
state: state,
|
||||||
info: info,
|
info: info,
|
||||||
engine: engine,
|
engine: engine,
|
||||||
|
factory: factory,
|
||||||
depth: depth,
|
depth: depth,
|
||||||
params: params,
|
params: params,
|
||||||
substate: substate,
|
substate: substate,
|
||||||
@ -323,7 +326,7 @@ impl<'a> Externalities<'a> {
|
|||||||
|
|
||||||
/// Creates `Externalities` from `Executive`.
|
/// Creates `Externalities` from `Executive`.
|
||||||
fn from_executive(e: &'a mut Executive, params: &'a ActionParams, substate: &'a mut Substate, output: OutputPolicy<'a>) -> Self {
|
fn from_executive(e: &'a mut Executive, params: &'a ActionParams, substate: &'a mut Substate, output: OutputPolicy<'a>) -> Self {
|
||||||
Self::new(e.state, e.info, e.engine, e.depth, params, substate, output)
|
Self::new(e.state, e.info, e.engine, e.factory, e.depth, params, substate, output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,7 +378,7 @@ impl<'a> Ext for Externalities<'a> {
|
|||||||
data: vec![],
|
data: vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ex = Executive::from_parent(self.state, self.info, self.engine, self.depth);
|
let mut ex = Executive::from_parent(self.state, self.info, self.engine, self.factory, self.depth);
|
||||||
ex.state.inc_nonce(&self.params.address);
|
ex.state.inc_nonce(&self.params.address);
|
||||||
ex.create(¶ms, self.substate).map(|gas_left| (gas_left, Some(address)))
|
ex.create(¶ms, self.substate).map(|gas_left| (gas_left, Some(address)))
|
||||||
}
|
}
|
||||||
@ -417,7 +420,7 @@ impl<'a> Ext for Externalities<'a> {
|
|||||||
data: data.to_vec(),
|
data: data.to_vec(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ex = Executive::from_parent(self.state, self.info, self.engine, self.depth);
|
let mut ex = Executive::from_parent(self.state, self.info, self.engine, self.factory, self.depth);
|
||||||
ex.call(¶ms, self.substate, BytesRef::Fixed(output))
|
ex.call(¶ms, self.substate, BytesRef::Fixed(output))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -491,6 +494,7 @@ mod tests {
|
|||||||
use engine::*;
|
use engine::*;
|
||||||
use spec::*;
|
use spec::*;
|
||||||
use evm::Schedule;
|
use evm::Schedule;
|
||||||
|
use evm::Factory;
|
||||||
|
|
||||||
struct TestEngine {
|
struct TestEngine {
|
||||||
spec: Spec,
|
spec: Spec,
|
||||||
@ -541,7 +545,8 @@ mod tests {
|
|||||||
let mut substate = Substate::new();
|
let mut substate = Substate::new();
|
||||||
|
|
||||||
let gas_left = {
|
let gas_left = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let factory = Factory::default();
|
||||||
|
let mut ex = Executive::new(&mut state, &info, &engine, &factory);
|
||||||
ex.create(¶ms, &mut substate).unwrap()
|
ex.create(¶ms, &mut substate).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -599,7 +604,8 @@ mod tests {
|
|||||||
let mut substate = Substate::new();
|
let mut substate = Substate::new();
|
||||||
|
|
||||||
let gas_left = {
|
let gas_left = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let factory = Factory::default();
|
||||||
|
let mut ex = Executive::new(&mut state, &info, &engine, &factory);
|
||||||
ex.create(¶ms, &mut substate).unwrap()
|
ex.create(¶ms, &mut substate).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -652,7 +658,8 @@ mod tests {
|
|||||||
let mut substate = Substate::new();
|
let mut substate = Substate::new();
|
||||||
|
|
||||||
let gas_left = {
|
let gas_left = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let factory = Factory::default();
|
||||||
|
let mut ex = Executive::new(&mut state, &info, &engine, &factory);
|
||||||
ex.create(¶ms, &mut substate).unwrap()
|
ex.create(¶ms, &mut substate).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -703,7 +710,8 @@ mod tests {
|
|||||||
let mut substate = Substate::new();
|
let mut substate = Substate::new();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let factory = Factory::default();
|
||||||
|
let mut ex = Executive::new(&mut state, &info, &engine, &factory);
|
||||||
ex.create(¶ms, &mut substate).unwrap();
|
ex.create(¶ms, &mut substate).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -761,7 +769,8 @@ mod tests {
|
|||||||
let mut substate = Substate::new();
|
let mut substate = Substate::new();
|
||||||
|
|
||||||
let gas_left = {
|
let gas_left = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let factory = Factory::default();
|
||||||
|
let mut ex = Executive::new(&mut state, &info, &engine, &factory);
|
||||||
ex.call(¶ms, &mut substate, BytesRef::Fixed(&mut [])).unwrap()
|
ex.call(¶ms, &mut substate, BytesRef::Fixed(&mut [])).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -803,7 +812,8 @@ mod tests {
|
|||||||
let mut substate = Substate::new();
|
let mut substate = Substate::new();
|
||||||
|
|
||||||
let gas_left = {
|
let gas_left = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let factory = Factory::default();
|
||||||
|
let mut ex = Executive::new(&mut state, &info, &engine, &factory);
|
||||||
ex.call(¶ms, &mut substate, BytesRef::Fixed(&mut [])).unwrap()
|
ex.call(¶ms, &mut substate, BytesRef::Fixed(&mut [])).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -827,7 +837,8 @@ mod tests {
|
|||||||
let engine = TestEngine::new(0);
|
let engine = TestEngine::new(0);
|
||||||
|
|
||||||
let executed = {
|
let executed = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let factory = Factory::default();
|
||||||
|
let mut ex = Executive::new(&mut state, &info, &engine, &factory);
|
||||||
ex.transact(&t).unwrap()
|
ex.transact(&t).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -854,7 +865,8 @@ mod tests {
|
|||||||
let engine = TestEngine::new(0);
|
let engine = TestEngine::new(0);
|
||||||
|
|
||||||
let res = {
|
let res = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let factory = Factory::default();
|
||||||
|
let mut ex = Executive::new(&mut state, &info, &engine, &factory);
|
||||||
ex.transact(&t)
|
ex.transact(&t)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -878,7 +890,8 @@ mod tests {
|
|||||||
let engine = TestEngine::new(0);
|
let engine = TestEngine::new(0);
|
||||||
|
|
||||||
let res = {
|
let res = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let factory = Factory::default();
|
||||||
|
let mut ex = Executive::new(&mut state, &info, &engine, &factory);
|
||||||
ex.transact(&t)
|
ex.transact(&t)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -904,7 +917,8 @@ mod tests {
|
|||||||
let engine = TestEngine::new(0);
|
let engine = TestEngine::new(0);
|
||||||
|
|
||||||
let res = {
|
let res = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let factory = Factory::default();
|
||||||
|
let mut ex = Executive::new(&mut state, &info, &engine, &factory);
|
||||||
ex.transact(&t)
|
ex.transact(&t)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -929,7 +943,8 @@ mod tests {
|
|||||||
let engine = TestEngine::new(0);
|
let engine = TestEngine::new(0);
|
||||||
|
|
||||||
let res = {
|
let res = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let factory = Factory::default();
|
||||||
|
let mut ex = Executive::new(&mut state, &info, &engine, &factory);
|
||||||
ex.transact(&t)
|
ex.transact(&t)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use common::*;
|
use common::*;
|
||||||
use engine::Engine;
|
use engine::Engine;
|
||||||
use executive::Executive;
|
use executive::Executive;
|
||||||
|
use evm::Factory;
|
||||||
|
|
||||||
pub type ApplyResult = Result<Receipt, Error>;
|
pub type ApplyResult = Result<Receipt, Error>;
|
||||||
|
|
||||||
@ -137,7 +138,8 @@ impl State {
|
|||||||
/// Execute a given transaction.
|
/// Execute a given transaction.
|
||||||
/// This will change the state accordingly.
|
/// This will change the state accordingly.
|
||||||
pub fn apply(&mut self, env_info: &EnvInfo, engine: &Engine, t: &Transaction) -> ApplyResult {
|
pub fn apply(&mut self, env_info: &EnvInfo, engine: &Engine, t: &Transaction) -> ApplyResult {
|
||||||
let e = try!(Executive::new(self, env_info, engine).transact(t));
|
// TODO [todr] Pass VM factory?
|
||||||
|
let e = try!(Executive::new(self, env_info, engine, &Factory::default()).transact(t));
|
||||||
self.commit();
|
self.commit();
|
||||||
Ok(Receipt::new(self.root().clone(), e.gas_used, e.logs))
|
Ok(Receipt::new(self.root().clone(), e.gas_used, e.logs))
|
||||||
}
|
}
|
||||||
|
@ -217,9 +217,10 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
|||||||
|
|
||||||
// execute
|
// execute
|
||||||
let (res, callcreates) = {
|
let (res, callcreates) = {
|
||||||
let ex = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::Return(BytesRef::Flexible(&mut output)));
|
let factory = Factory::default();
|
||||||
|
let ex = Externalities::new(&mut state, &info, &engine, &factory, 0, ¶ms, &mut substate, OutputPolicy::Return(BytesRef::Flexible(&mut output)));
|
||||||
let mut test_ext = TestExt::new(ex);
|
let mut test_ext = TestExt::new(ex);
|
||||||
let evm = Factory::create();
|
let evm = Factory::default().create();
|
||||||
let res = evm.exec(¶ms, &mut test_ext);
|
let res = evm.exec(¶ms, &mut test_ext);
|
||||||
(res, test_ext.callcreates)
|
(res, test_ext.callcreates)
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user