This repository was archived by the owner on Oct 28, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Expand file tree
/
Copy pathEVMC.cpp
More file actions
78 lines (62 loc) · 2.13 KB
/
EVMC.cpp
File metadata and controls
78 lines (62 loc) · 2.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// Copyright 2018 cpp-ethereum Authors.
// Licensed under the GNU General Public License v3. See the LICENSE file.
#include "EVMC.h"
#include <libdevcore/Log.h>
#include <libevm/VM.h>
#include <libevm/VMFactory.h>
namespace dev
{
namespace eth
{
EVM::EVM(evm_instance* _instance) noexcept : m_instance(_instance)
{
assert(m_instance != nullptr);
assert(m_instance->abi_version == EVM_ABI_VERSION);
// Set the options.
for (auto& pair : evmcOptions())
m_instance->set_option(m_instance, pair.first.c_str(), pair.second.c_str());
}
owning_bytes_ref EVMC::exec(u256& io_gas, ExtVMFace& _ext, const OnOpFunc& _onOp)
{
assert(_ext.envInfo().number() >= 0);
assert(_ext.envInfo().timestamp() >= 0);
constexpr int64_t int64max = std::numeric_limits<int64_t>::max();
// TODO: The following checks should be removed by changing the types
// used for gas, block number and timestamp.
(void)int64max;
assert(io_gas <= int64max);
assert(_ext.envInfo().gasLimit() <= int64max);
assert(_ext.depth <= std::numeric_limits<int32_t>::max());
auto gas = static_cast<int64_t>(io_gas);
EVM::Result r = execute(_ext, gas);
if (r.status() == EVM_REJECTED)
{
cwarn << "Execution rejected by EVM-C, executing with interpreter";
return VMFactory::create(VMKind::Interpreter)->exec(io_gas, _ext, _onOp);
}
// TODO: Add EVM-C result codes mapping with exception types.
if (r.status() == EVM_FAILURE)
BOOST_THROW_EXCEPTION(OutOfGas());
io_gas = r.gasLeft();
// FIXME: Copy the output for now, but copyless version possible.
owning_bytes_ref output{r.output().toVector(), 0, r.output().size()};
if (r.status() == EVM_REVERT)
throw RevertInstruction(std::move(output));
return output;
}
evm_revision toRevision(EVMSchedule const& _schedule)
{
if (_schedule.haveCreate2)
return EVM_CONSTANTINOPLE;
if (_schedule.haveRevert)
return EVM_BYZANTIUM;
if (_schedule.eip158Mode)
return EVM_SPURIOUS_DRAGON;
if (_schedule.eip150Mode)
return EVM_TANGERINE_WHISTLE;
if (_schedule.haveDelegateCall)
return EVM_HOMESTEAD;
return EVM_FRONTIER;
}
}
}