Browse Source

Introducing VMFace - common VM interface

cl-refactor
Paweł Bylica 10 years ago
parent
commit
94df0ea77f
  1. 42
      libevm/VM.cpp
  2. 36
      libevm/VM.h
  3. 61
      libevm/VMFace.h
  4. 3
      windows/LibEthereum.vcxproj
  5. 11
      windows/LibEthereum.vcxproj.filters

42
libevm/VM.cpp

@ -1,33 +1,41 @@
/*
This file is part of cpp-ethereum.
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file VM.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "VM.h"
#include <libethereum/ExtVM.h>
using namespace std;
using namespace dev;
using namespace dev::eth;
void VM::reset(u256 _gas)
void VM::reset(u256 _gas) noexcept
{
m_gas = _gas;
VMFace::reset(_gas);
m_curPC = 0;
m_jumpDests.clear();
}
bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps)
{
if (auto defaultExt = dynamic_cast<ExtVM*>(&_ext))
return goImpl<ExtVM>(*defaultExt, _onOp, _steps);
else
return goImpl<ExtVMFace>(_ext, _onOp, _steps);
}

36
libevm/VM.h

@ -28,21 +28,13 @@
#include <libdevcrypto/SHA3.h>
#include <libethcore/BlockInfo.h>
#include "FeeStructure.h"
#include "ExtVMFace.h"
#include "VMFace.h"
namespace dev
{
namespace eth
{
struct VMException: virtual Exception {};
struct StepsDone: virtual VMException {};
struct BreakPointHit: virtual VMException {};
struct BadInstruction: virtual VMException {};
struct BadJumpDestination: virtual VMException {};
struct OutOfGas: virtual VMException {};
struct StackTooSmall: virtual public VMException {};
// Convert from a 256-bit integer stack/memory entry into a 160-bit Address hash.
// Currently we just pull out the right (low-order in BE) 160-bits.
inline Address asAddress(u256 _item)
@ -57,28 +49,28 @@ inline u256 fromAddress(Address _a)
/**
*/
class VM
class VM : public VMFace
{
public:
/// Construct VM object.
explicit VM(u256 _gas = 0) { reset(_gas); }
explicit VM(u256 _gas = 0) : VMFace(_gas) {}
void reset(u256 _gas = 0);
virtual void reset(u256 _gas = 0) noexcept override final;
template <class Ext>
bytesConstRef go(Ext& _ext, OnOpFunc const& _onOp = OnOpFunc(), uint64_t _steps = (uint64_t)-1);
virtual bytesConstRef go(ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) override final;
void require(u256 _n) { if (m_stack.size() < _n) { if (m_onFail) m_onFail(); BOOST_THROW_EXCEPTION(StackTooSmall() << RequirementError((bigint)_n, (bigint)m_stack.size())); } }
void requireMem(unsigned _n) { if (m_temp.size() < _n) { m_temp.resize(_n); } }
u256 gas() const { return m_gas; }
u256 curPC() const { return m_curPC; }
bytes const& memory() const { return m_temp; }
u256s const& stack() const { return m_stack; }
private:
u256 m_gas = 0;
template <class Ext>
bytesConstRef goImpl(Ext& _ext, OnOpFunc const& _onOp = OnOpFunc(), uint64_t _steps = (uint64_t)-1);
u256 m_curPC = 0;
bytes m_temp;
u256s m_stack;
@ -89,7 +81,7 @@ private:
}
// INLINE:
template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc const& _onOp, uint64_t _steps)
template <class Ext> dev::bytesConstRef dev::eth::VM::goImpl(Ext& _ext, OnOpFunc const& _onOp, uint64_t _steps)
{
auto memNeed = [](dev::u256 _offset, dev::u256 _size) { return _size ? (bigint)_offset + _size : (bigint)0; };
@ -164,7 +156,7 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
case Instruction::SLOAD:
require(1);
runGas = c_sloadGas;
runGas = c_sloadGas;
break;
// These all operate on memory and therefore potentially expand it:
@ -412,7 +404,7 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
m_stack.pop_back();
break;
case Instruction::SDIV:
m_stack[m_stack.size() - 2] = m_stack[m_stack.size() - 2] ? s2u(u2s(m_stack.back()) / u2s(m_stack[m_stack.size() - 2])) : 0;
m_stack[m_stack.size() - 2] = m_stack[m_stack.size() - 2] ? s2u(u2s(m_stack.back()) / u2s(m_stack[m_stack.size() - 2])) : 0;
m_stack.pop_back();
break;
case Instruction::MOD:
@ -420,7 +412,7 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
m_stack.pop_back();
break;
case Instruction::SMOD:
m_stack[m_stack.size() - 2] = m_stack[m_stack.size() - 2] ? s2u(u2s(m_stack.back()) % u2s(m_stack[m_stack.size() - 2])) : 0;
m_stack[m_stack.size() - 2] = m_stack[m_stack.size() - 2] ? s2u(u2s(m_stack.back()) % u2s(m_stack[m_stack.size() - 2])) : 0;
m_stack.pop_back();
break;
case Instruction::EXP:
@ -443,11 +435,11 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
m_stack.pop_back();
break;
case Instruction::SLT:
m_stack[m_stack.size() - 2] = u2s(m_stack.back()) < u2s(m_stack[m_stack.size() - 2]) ? 1 : 0;
m_stack[m_stack.size() - 2] = u2s(m_stack.back()) < u2s(m_stack[m_stack.size() - 2]) ? 1 : 0;
m_stack.pop_back();
break;
case Instruction::SGT:
m_stack[m_stack.size() - 2] = u2s(m_stack.back()) > u2s(m_stack[m_stack.size() - 2]) ? 1 : 0;
m_stack[m_stack.size() - 2] = u2s(m_stack.back()) > u2s(m_stack[m_stack.size() - 2]) ? 1 : 0;
m_stack.pop_back();
break;
case Instruction::EQ:

61
libevm/VMFace.h

@ -0,0 +1,61 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <memory>
#include <libdevcore/Exceptions.h>
#include "ExtVMFace.h"
namespace dev
{
namespace eth
{
struct VMException : virtual Exception {};
struct StepsDone : virtual VMException {};
struct BreakPointHit : virtual VMException {};
struct BadInstruction : virtual VMException {};
struct BadJumpDestination : virtual VMException {};
struct OutOfGas : virtual VMException {};
struct StackTooSmall : virtual public VMException {};
/**
*/
class VMFace
{
public:
/// Construct VM object.
explicit VMFace(u256 _gas = 0): m_gas(_gas) {}
virtual ~VMFace() = default;
VMFace(VMFace const&) = delete;
void operator=(VMFace const&) = delete;
virtual void reset(u256 _gas = 0) noexcept { m_gas = _gas; }
virtual bytesConstRef go(ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) = 0;
u256 gas() const { return m_gas; }
protected:
u256 m_gas = 0;
};
}
}

3
windows/LibEthereum.vcxproj

@ -368,6 +368,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="..\libevm\VMFace.h" />
<ClInclude Include="..\liblll\All.h" />
<ClInclude Include="..\liblll\CodeFragment.h" />
<ClInclude Include="..\liblll\Compiler.h" />
@ -568,4 +569,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

11
windows/LibEthereum.vcxproj.filters

@ -190,18 +190,14 @@
<ClCompile Include="..\libdevcrypto\CryptoPP.cpp">
<Filter>libdevcrypto</Filter>
</ClCompile>
<ClCompile Include="..\libdevcrypto\EC.cpp">
<Filter>libdevcrypto</Filter>
</ClCompile>
<ClCompile Include="..\libdevcrypto\SHA3MAC.cpp">
<Filter>libdevcrypto</Filter>
</ClCompile>
<ClCompile Include="..\libethereum\Account.cpp">
<Filter>libethereum</Filter>
</ClCompile>
<ClCompile Include="..\libevmcore\Assembly.cpp">
<Filter>libevmcore</Filter>
</ClCompile>
<ClCompile Include="..\libdevcrypto\AES.cpp" />
<ClCompile Include="..\libdevcrypto\ECDHE.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
@ -438,6 +434,9 @@
<ClInclude Include="..\libevmcore\Assembly.h">
<Filter>libevmcore</Filter>
</ClInclude>
<ClInclude Include="..\libevm\VMFace.h">
<Filter>libevm</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Windows">

Loading…
Cancel
Save