From 1f17c569b961123ef97def7bfebc1266a2e4cd79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Wed, 27 May 2015 13:23:00 +0200 Subject: [PATCH] Change VM interface to return a copy of output. --- evmjit/libevmjit-cpp/JitVM.cpp | 4 ++-- evmjit/libevmjit-cpp/JitVM.h | 2 +- libethereum/Executive.cpp | 12 +++++------- libethereum/Executive.h | 5 ++--- libevm/SmartVM.cpp | 4 ++-- libevm/SmartVM.h | 2 +- libevm/VM.cpp | 2 +- libevm/VM.h | 2 +- libevm/VMFace.h | 7 ++++++- test/fuzzTesting/checkRandomVMTest.cpp | 4 ++-- test/fuzzTesting/createRandomVMTest.cpp | 2 +- test/libevm/vm.cpp | 4 +--- 12 files changed, 25 insertions(+), 25 deletions(-) diff --git a/evmjit/libevmjit-cpp/JitVM.cpp b/evmjit/libevmjit-cpp/JitVM.cpp index 5193168a4..ac8df545f 100644 --- a/evmjit/libevmjit-cpp/JitVM.cpp +++ b/evmjit/libevmjit-cpp/JitVM.cpp @@ -18,7 +18,7 @@ namespace eth extern "C" void env_sload(); // fake declaration for linker symbol stripping workaround, see a call below -bytesConstRef JitVM::go(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _step) +bytesConstRef JitVM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _step) { using namespace jit; @@ -33,7 +33,7 @@ bytesConstRef JitVM::go(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp, ui { cwarn << "Execution rejected by EVM JIT (gas limit: " << io_gas << "), executing with interpreter"; m_fallbackVM = VMFactory::create(VMKind::Interpreter); - return m_fallbackVM->go(io_gas, _ext, _onOp, _step); + return m_fallbackVM->execImpl(io_gas, _ext, _onOp, _step); } m_data.gas = static_cast(io_gas); diff --git a/evmjit/libevmjit-cpp/JitVM.h b/evmjit/libevmjit-cpp/JitVM.h index e6864f885..7c8b4ceb8 100644 --- a/evmjit/libevmjit-cpp/JitVM.h +++ b/evmjit/libevmjit-cpp/JitVM.h @@ -11,7 +11,7 @@ namespace eth class JitVM: public VMFace { public: - virtual bytesConstRef go(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) override final; + virtual bytesConstRef execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) override final; private: jit::RuntimeData m_data; diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index d7bad0ff9..122432d85 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -46,7 +46,7 @@ u256 Executive::gasUsed() const ExecutionResult Executive::executionResult() const { - return ExecutionResult(gasUsed(), m_excepted, m_newAddress, m_out, m_codeDeposit, m_ext ? m_ext->sub.refunds : 0, m_depositSize, m_gasForDeposit); + return ExecutionResult(gasUsed(), m_excepted, m_newAddress, out(), m_codeDeposit, m_ext ? m_ext->sub.refunds : 0, m_depositSize, m_gasForDeposit); } void Executive::accrueSubState(SubState& _parentContext) @@ -145,8 +145,7 @@ bool Executive::call(CallParameters const& _p, u256 const& _gasPrice, Address co else { m_gas = (u256)(_p.gas - g); - m_precompiledOut = it->second.exec(_p.data); - m_out = &m_precompiledOut; + m_out = it->second.exec(_p.data); } } else @@ -219,7 +218,7 @@ bool Executive::go(OnOpFunc const& _onOp) #endif try { - m_out = m_vm->go(m_gas, *m_ext, _onOp); + m_out = m_vm->exec(m_gas, *m_ext, _onOp); if (m_isCreation) { @@ -232,11 +231,10 @@ bool Executive::go(OnOpFunc const& _onOp) } else { - m_codeDeposit = CodeDeposit::Failed; - m_out.reset(); + m_out.clear(); } - m_s.m_cache[m_newAddress].setCode(m_out.toBytes()); + m_s.m_cache[m_newAddress].setCode(std::move(m_out)); } } catch (StepsDone const&) diff --git a/libethereum/Executive.h b/libethereum/Executive.h index 04d5857b3..bd9fb178e 100644 --- a/libethereum/Executive.h +++ b/libethereum/Executive.h @@ -109,7 +109,7 @@ public: /// @returns gas remaining after the transaction/operation. Valid after the transaction has been executed. u256 gas() const { return m_gas; } /// @returns output data of the transaction/operation. - bytesConstRef out() const { return m_out; } + bytesConstRef out() const { return {m_out.data(), m_out.size()}; } /// @returns the new address for the created contract in the CREATE operation. h160 newAddress() const { return m_newAddress; } /// @returns true iff the operation ended with a VM exception. @@ -123,8 +123,7 @@ private: LastHashes m_lastHashes; std::shared_ptr m_ext; ///< The VM externality object for the VM execution or null if no VM is required. std::unique_ptr m_vm; ///< The VM object or null if no VM is required. - bytes m_precompiledOut; ///< Used for the output when there is no VM for a contract (i.e. precompiled). - bytesConstRef m_out; ///< The copyable output. + bytes m_out; ///< The VM execution output. Address m_newAddress; ///< The address of the created contract in the case of create() being called. unsigned m_depth = 0; ///< The context's call-depth. diff --git a/libevm/SmartVM.cpp b/libevm/SmartVM.cpp index d37abc1bf..27263fc2d 100644 --- a/libevm/SmartVM.cpp +++ b/libevm/SmartVM.cpp @@ -41,7 +41,7 @@ namespace } } -bytesConstRef SmartVM::go(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps) +bytesConstRef SmartVM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps) { auto codeHash = sha3(_ext.code); auto vmKind = VMKind::Interpreter; // default VM @@ -68,7 +68,7 @@ bytesConstRef SmartVM::go(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp, // TODO: Selected VM must be kept only because it returns reference to its internal memory. // VM implementations should be stateless, without escaping memory reference. m_selectedVM = VMFactory::create(vmKind); - return m_selectedVM->go(io_gas, _ext, _onOp, _steps); + return m_selectedVM->execImpl(io_gas, _ext, _onOp, _steps); } } diff --git a/libevm/SmartVM.h b/libevm/SmartVM.h index cc198c0c2..01e163cd2 100644 --- a/libevm/SmartVM.h +++ b/libevm/SmartVM.h @@ -31,7 +31,7 @@ namespace eth class SmartVM: public VMFace { public: - virtual bytesConstRef go(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) override final; + virtual bytesConstRef execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) override final; private: std::unique_ptr m_selectedVM; diff --git a/libevm/VM.cpp b/libevm/VM.cpp index df8432ac6..3a4124d67 100644 --- a/libevm/VM.cpp +++ b/libevm/VM.cpp @@ -45,7 +45,7 @@ static array metrics() return s_ret; } -bytesConstRef VM::go(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps) +bytesConstRef VM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps) { // Reset leftovers from possible previous run m_curPC = 0; diff --git a/libevm/VM.h b/libevm/VM.h index 99f608227..0a33e9fae 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -52,7 +52,7 @@ inline u256 fromAddress(Address _a) class VM: public VMFace { public: - virtual bytesConstRef go(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) override final; + virtual bytesConstRef execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) override final; u256 curPC() const { return m_curPC; } diff --git a/libevm/VMFace.h b/libevm/VMFace.h index d2a12e0ca..8fd7ebcb3 100644 --- a/libevm/VMFace.h +++ b/libevm/VMFace.h @@ -43,7 +43,12 @@ public: VMFace(VMFace const&) = delete; VMFace& operator=(VMFace const&) = delete; - virtual bytesConstRef go(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) = 0; + bytes exec(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) + { + return execImpl(io_gas, _ext, _onOp, _steps).toVector(); + } + + virtual bytesConstRef execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) = 0; }; } diff --git a/test/fuzzTesting/checkRandomVMTest.cpp b/test/fuzzTesting/checkRandomVMTest.cpp index 13d677e17..a6ade07f1 100644 --- a/test/fuzzTesting/checkRandomVMTest.cpp +++ b/test/fuzzTesting/checkRandomVMTest.cpp @@ -98,9 +98,9 @@ bool doVMTest(mValue& _v) try { auto vm = eth::VMFactory::create(); - output = vm->go(fev.gas, fev, fev.simpleTrace()).toBytes(); + output = vm->exec(fev.gas, fev, fev.simpleTrace()); } - catch (eth::VMException) + catch (eth::VMException const&) { cnote << "Safe VM Exception"; vmExceptionOccured = true; diff --git a/test/fuzzTesting/createRandomVMTest.cpp b/test/fuzzTesting/createRandomVMTest.cpp index 3196590d4..93040d6de 100644 --- a/test/fuzzTesting/createRandomVMTest.cpp +++ b/test/fuzzTesting/createRandomVMTest.cpp @@ -160,7 +160,7 @@ void doMyTests(json_spirit::mValue& _v) bool vmExceptionOccured = false; try { - output = vm->go(fev.gas, fev, fev.simpleTrace()).toBytes(); + output = vm->exec(fev.gas, fev, fev.simpleTrace()); } catch (eth::VMException const& _e) { diff --git a/test/libevm/vm.cpp b/test/libevm/vm.cpp index cb63e993c..c407c8184 100644 --- a/test/libevm/vm.cpp +++ b/test/libevm/vm.cpp @@ -329,12 +329,10 @@ void doVMTests(json_spirit::mValue& v, bool _fillin) { auto vm = eth::VMFactory::create(); auto vmtrace = Options::get().vmtrace ? fev.simpleTrace() : OnOpFunc{}; - auto outputRef = bytesConstRef{}; { Listener::ExecTimeGuard guard{i.first}; - outputRef = vm->go(fev.gas, fev, vmtrace); + output = vm->exec(fev.gas, fev, vmtrace); } - output = outputRef.toBytes(); } catch (VMException const&) {