Parametrizing evm::Factory
This commit is contained in:
parent
eebcd0f35b
commit
81720d6617
@ -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<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")]
|
||||
pub fn create() -> Box<Evm> {
|
||||
fn jit() -> Box<Evm> {
|
||||
Box::new(super::jit::JitEvm)
|
||||
}
|
||||
|
||||
/// Returns native rust evm
|
||||
#[cfg(not(feature = "jit"))]
|
||||
pub fn create() -> Box<Evm> {
|
||||
Box::new(super::interpreter::Interpreter)
|
||||
fn jit() -> Box<Evm> {
|
||||
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();
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -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)
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
use common::*;
|
||||
use engine::Engine;
|
||||
use executive::Executive;
|
||||
use evm::Factory;
|
||||
|
||||
pub type ApplyResult = Result<Receipt, Error>;
|
||||
|
||||
@ -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))
|
||||
}
|
||||
|
@ -217,9 +217,10 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
||||
|
||||
// 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)
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user