diff --git a/src/evm/factory.rs b/src/evm/factory.rs index 39019cd8d..b2f989dbe 100644 --- a/src/evm/factory.rs +++ b/src/evm/factory.rs @@ -2,24 +2,63 @@ use evm::Evm; +pub enum VMType { + Jit, + Interpreter +} + /// Evm factory. Creates appropriate Evm. -pub struct Factory; +pub struct Factory { + evm : VMType +} impl Factory { - /// Returns jit vm + + pub fn create(&self) -> Box { + 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")] - pub fn create() -> Box { + fn jit() -> Box { Box::new(super::jit::JitEvm) } - /// Returns native rust evm #[cfg(not(feature = "jit"))] - pub fn create() -> Box { - Box::new(super::interpreter::Interpreter) + fn jit() -> Box { + 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] fn test_create_vm() { - let _vm = Factory::create(); + let _vm = Factory::default().create(); } diff --git a/src/evm/tests.rs b/src/evm/tests.rs index ab5dd9dbd..ae74544c5 100644 --- a/src/evm/tests.rs +++ b/src/evm/tests.rs @@ -127,11 +127,11 @@ macro_rules! evm_test( #[test] #[cfg(feature = "jit")] fn $name_jit() { - $name_test(Box::new(super::jit::JitEvm)); + $name_test(super::Factory::new(super::factory::VMType::Jit).create()); } #[test] fn $name_int() { - $name_test(Box::new(super::interpreter::Interpreter)); + $name_test(super::Factory::new(super::factory::VMType::Interpreter).create()); } } ); diff --git a/src/executive.rs b/src/executive.rs index 370eb7c0b..8212cc0fd 100644 --- a/src/executive.rs +++ b/src/executive.rs @@ -74,27 +74,29 @@ pub struct Executive<'a> { state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, + factory: &'a Factory, depth: usize } impl<'a> Executive<'a> { /// Basic constructor. - pub fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine) -> Self { - Executive::new_with_depth(state, info, engine, 0) + pub fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, factory: &'a Factory) -> Self { + Executive::new_with_depth(state, info, engine, factory, 0) } /// Populates executive from parent properties. Increments executive depth. - fn from_parent(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, depth: usize) -> Self { - Executive::new_with_depth(state, info, engine, depth + 1) + 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, factory, depth + 1) } /// Helper constructor. Should be used to create `Executive` with desired depth. /// 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 { state: state, info: info, engine: engine, + factory: factory, depth: depth } } @@ -191,8 +193,7 @@ impl<'a> Executive<'a> { } else if params.code.len() > 0 { // if destination is a contract, do normal message call let mut ext = Externalities::from_executive(self, params, substate, OutputPolicy::Return(output)); - let evm = Factory::create(); - evm.exec(¶ms, &mut ext) + self.factory.create().exec(¶ms, &mut ext) } else { // otherwise, nothing Ok(params.gas) @@ -209,8 +210,7 @@ impl<'a> Executive<'a> { self.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value); let mut ext = Externalities::from_executive(self, params, substate, OutputPolicy::InitContract); - let evm = Factory::create(); - evm.exec(¶ms, &mut ext) + self.factory.create().exec(¶ms, &mut ext) } /// Finalizes the transaction (does refunds and suicides). @@ -290,6 +290,7 @@ pub struct Externalities<'a> { state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, + factory: &'a Factory, depth: usize, #[cfg(test)] pub params: &'a ActionParams, @@ -304,7 +305,8 @@ impl<'a> Externalities<'a> { /// Basic `Externalities` constructor. pub fn new(state: &'a mut State, info: &'a EnvInfo, - engine: &'a Engine, + engine: &'a Engine, + factory: &'a Factory, depth: usize, params: &'a ActionParams, substate: &'a mut Substate, @@ -313,6 +315,7 @@ impl<'a> Externalities<'a> { state: state, info: info, engine: engine, + factory: factory, depth: depth, params: params, substate: substate, @@ -323,7 +326,7 @@ impl<'a> Externalities<'a> { /// Creates `Externalities` from `Executive`. 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![], }; - 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.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(), }; - 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)) } @@ -491,6 +494,7 @@ mod tests { use engine::*; use spec::*; use evm::Schedule; + use evm::Factory; struct TestEngine { spec: Spec, @@ -541,7 +545,8 @@ mod tests { let mut substate = Substate::new(); 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() }; @@ -599,7 +604,8 @@ mod tests { let mut substate = Substate::new(); 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() }; @@ -652,7 +658,8 @@ mod tests { let mut substate = Substate::new(); 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() }; @@ -703,7 +710,8 @@ mod tests { 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(); } @@ -761,7 +769,8 @@ mod tests { let mut substate = Substate::new(); 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() }; @@ -803,7 +812,8 @@ mod tests { let mut substate = Substate::new(); 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() }; @@ -827,7 +837,8 @@ mod tests { let engine = TestEngine::new(0); 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() }; @@ -854,7 +865,8 @@ mod tests { let engine = TestEngine::new(0); 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) }; @@ -878,7 +890,8 @@ mod tests { let engine = TestEngine::new(0); 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) }; @@ -904,7 +917,8 @@ mod tests { let engine = TestEngine::new(0); 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) }; @@ -929,7 +943,8 @@ mod tests { let engine = TestEngine::new(0); 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) }; diff --git a/src/state.rs b/src/state.rs index a236e08c5..0eecc78da 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,6 +1,7 @@ use common::*; use engine::Engine; use executive::Executive; +use evm::Factory; pub type ApplyResult = Result; @@ -137,7 +138,8 @@ impl State { /// Execute a given transaction. /// This will change the state accordingly. 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(); Ok(Receipt::new(self.root().clone(), e.gas_used, e.logs)) } diff --git a/src/tests/executive.rs b/src/tests/executive.rs index d49ac5f8b..bf3815b5c 100644 --- a/src/tests/executive.rs +++ b/src/tests/executive.rs @@ -217,9 +217,10 @@ fn do_json_test(json_data: &[u8]) -> Vec { // execute 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 evm = Factory::create(); + let evm = Factory::default().create(); let res = evm.exec(¶ms, &mut test_ext); (res, test_ext.callcreates) };