diff --git a/libevm/VM.cpp b/libevm/VM.cpp
index bded9a10d..996e51eea 100644
--- a/libevm/VM.cpp
+++ b/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 .
+You should have received a copy of the GNU General Public License
+along with cpp-ethereum. If not, see .
*/
/** @file VM.cpp
- * @author Gav Wood
- * @date 2014
- */
+* @author Gav Wood
+* @date 2014
+*/
#include "VM.h"
+#include
-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(&_ext))
+ return goImpl(*defaultExt, _onOp, _steps);
+ else
+ return goImpl(_ext, _onOp, _steps);
+}
diff --git a/libevm/VM.h b/libevm/VM.h
index 5fb46fc68..bb34bceb2 100644
--- a/libevm/VM.h
+++ b/libevm/VM.h
@@ -28,21 +28,13 @@
#include
#include
#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
- 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
+ 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 dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc const& _onOp, uint64_t _steps)
+template 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 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 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 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 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:
diff --git a/libevm/VMFace.h b/libevm/VMFace.h
new file mode 100644
index 000000000..f6db7d0b5
--- /dev/null
+++ b/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 .
+*/
+
+#pragma once
+
+#include
+#include
+#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;
+};
+
+}
+}
diff --git a/windows/LibEthereum.vcxproj b/windows/LibEthereum.vcxproj
index 06f868023..cbacd51b5 100644
--- a/windows/LibEthereum.vcxproj
+++ b/windows/LibEthereum.vcxproj
@@ -368,6 +368,7 @@
true
true
+
@@ -568,4 +569,4 @@
-
+
\ No newline at end of file
diff --git a/windows/LibEthereum.vcxproj.filters b/windows/LibEthereum.vcxproj.filters
index 114364008..76201d823 100644
--- a/windows/LibEthereum.vcxproj.filters
+++ b/windows/LibEthereum.vcxproj.filters
@@ -190,18 +190,14 @@
libdevcrypto
-
- libdevcrypto
-
-
- libdevcrypto
-
libethereum
libevmcore
+
+
@@ -438,6 +434,9 @@
libevmcore
+
+ libevm
+