Skip to content
This repository was archived by the owner on Oct 28, 2021. It is now read-only.

Commit df1517f

Browse files
committed
Get rid of global variables for trace function and context.
Store them as member variables of a class wrapping evmc_instance.
1 parent e89c186 commit df1517f

File tree

2 files changed

+83
-62
lines changed

2 files changed

+83
-62
lines changed

libaleth-interpreter/VM.cpp

Lines changed: 79 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -22,87 +22,102 @@
2222

2323
namespace
2424
{
25-
evmc_trace_callback g_traceCallback = nullptr;
26-
evmc_tracer_context* g_traceContext = nullptr;
27-
28-
void destroy(evmc_instance* _instance)
29-
{
30-
(void)_instance;
31-
}
3225

3326
void delete_output(const evmc_result* result)
3427
{
3528
delete[] result->output_data;
3629
}
3730

38-
evmc_result execute(evmc_instance* _instance, evmc_context* _context, evmc_revision _rev,
39-
evmc_message const* _msg, uint8_t const* _code, size_t _codeSize) noexcept
31+
class InterpreterEvmcInstance : public evmc_instance
4032
{
41-
(void)_instance;
42-
std::unique_ptr<dev::eth::VM> vm{new dev::eth::VM};
33+
public:
34+
static InterpreterEvmcInstance* create() { return new InterpreterEvmcInstance{}; }
4335

44-
evmc_result result = {};
45-
dev::eth::owning_bytes_ref output;
46-
47-
try
48-
{
49-
output = vm->exec(_context, _rev, _msg, _code, _codeSize);
50-
result.status_code = EVMC_SUCCESS;
51-
result.gas_left = vm->m_io_gas;
52-
}
53-
catch (dev::eth::RevertInstruction& ex)
54-
{
55-
result.status_code = EVMC_REVERT;
56-
result.gas_left = vm->m_io_gas;
57-
output = ex.output(); // This moves the output from the exception!
58-
}
59-
catch (dev::eth::BadInstruction const&)
60-
{
61-
result.status_code = EVMC_UNDEFINED_INSTRUCTION;
62-
}
63-
catch (dev::eth::DisallowedStateChange const&)
36+
private:
37+
InterpreterEvmcInstance()
38+
: evmc_instance{
39+
EVMC_ABI_VERSION, "interpreter", aleth_get_buildinfo()->project_version, destroy,
40+
execute, setTracer,
41+
nullptr, // set_option
42+
}
6443
{
65-
result.status_code = EVMC_STATIC_MODE_VIOLATION;
6644
}
67-
catch (dev::eth::VMException const&)
45+
46+
static void destroy(evmc_instance* _instance)
6847
{
69-
result.status_code = EVMC_FAILURE;
48+
delete static_cast<InterpreterEvmcInstance*>(_instance);
7049
}
71-
catch (...)
50+
51+
static evmc_result execute(evmc_instance* _instance, evmc_context* _context, evmc_revision _rev,
52+
evmc_message const* _msg, uint8_t const* _code, size_t _codeSize) noexcept
7253
{
73-
result.status_code = EVMC_INTERNAL_ERROR;
54+
std::unique_ptr<dev::eth::VM> vm{new dev::eth::VM};
55+
56+
evmc_result result = {};
57+
dev::eth::owning_bytes_ref output;
58+
59+
auto evmc = static_cast<InterpreterEvmcInstance*>(_instance);
60+
try
61+
{
62+
output = vm->exec(_context, _rev, _msg, _code, _codeSize, evmc->m_traceCallback,
63+
evmc->m_traceContext);
64+
result.status_code = EVMC_SUCCESS;
65+
result.gas_left = vm->m_io_gas;
66+
}
67+
catch (dev::eth::RevertInstruction& ex)
68+
{
69+
result.status_code = EVMC_REVERT;
70+
result.gas_left = vm->m_io_gas;
71+
output = ex.output(); // This moves the output from the exception!
72+
}
73+
catch (dev::eth::BadInstruction const&)
74+
{
75+
result.status_code = EVMC_UNDEFINED_INSTRUCTION;
76+
}
77+
catch (dev::eth::DisallowedStateChange const&)
78+
{
79+
result.status_code = EVMC_STATIC_MODE_VIOLATION;
80+
}
81+
catch (dev::eth::VMException const&)
82+
{
83+
result.status_code = EVMC_FAILURE;
84+
}
85+
catch (...)
86+
{
87+
result.status_code = EVMC_INTERNAL_ERROR;
88+
}
89+
90+
if (!output.empty())
91+
{
92+
// Make a copy of the output.
93+
auto outputData = new uint8_t[output.size()];
94+
std::memcpy(outputData, output.data(), output.size());
95+
result.output_data = outputData;
96+
result.output_size = output.size();
97+
result.release = delete_output;
98+
}
99+
100+
return result;
74101
}
75102

76-
if (!output.empty())
103+
static void setTracer(evmc_instance* _instance, evmc_trace_callback _callback,
104+
evmc_tracer_context* _context) noexcept
77105
{
78-
// Make a copy of the output.
79-
auto outputData = new uint8_t[output.size()];
80-
std::memcpy(outputData, output.data(), output.size());
81-
result.output_data = outputData;
82-
result.output_size = output.size();
83-
result.release = delete_output;
106+
auto evmc = static_cast<InterpreterEvmcInstance*>(_instance);
107+
108+
evmc->m_traceCallback = _callback;
109+
evmc->m_traceContext = _context;
84110
}
85111

86-
return result;
87-
}
112+
evmc_trace_callback m_traceCallback = nullptr;
113+
evmc_tracer_context* m_traceContext = nullptr;
114+
};
88115

89-
void setTracer(evmc_instance* /*_instance*/, evmc_trace_callback _callback,
90-
evmc_tracer_context* _context) noexcept
91-
{
92-
g_traceCallback = _callback;
93-
g_traceContext = _context;
94-
}
95116
} // namespace
96117

97118
extern "C" evmc_instance* evmc_create_interpreter() noexcept
98119
{
99-
// TODO: Allow creating multiple instances with different configurations.
100-
static evmc_instance s_instance{
101-
EVMC_ABI_VERSION, "interpreter", aleth_get_buildinfo()->project_version, ::destroy,
102-
::execute, ::setTracer,
103-
nullptr, // set_option
104-
};
105-
return &s_instance;
120+
return InterpreterEvmcInstance::create();
106121
}
107122

108123
namespace dev
@@ -111,7 +126,7 @@ namespace eth
111126
{
112127
void VM::trace() noexcept
113128
{
114-
if (g_traceCallback)
129+
if (m_traceCallback)
115130
{
116131
auto const& metrics = c_metrics[static_cast<size_t>(m_OP)];
117132
evmc_uint256be topStackItem;
@@ -121,7 +136,7 @@ void VM::trace() noexcept
121136
topStackItem = toEvmC(m_SPP[0]);
122137
pushedStackItem = &topStackItem;
123138
}
124-
g_traceCallback(g_traceContext, m_PC, EVMC_SUCCESS, m_io_gas, m_stackEnd - m_SPP,
139+
m_traceCallback(m_traceContext, m_PC, EVMC_SUCCESS, m_io_gas, m_stackEnd - m_SPP,
125140
pushedStackItem, m_mem.size(), 0, 0, nullptr);
126141
}
127142
}
@@ -269,7 +284,8 @@ evmc_tx_context const& VM::getTxContext()
269284
// interpreter entry point
270285

271286
owning_bytes_ref VM::exec(evmc_context* _context, evmc_revision _rev, const evmc_message* _msg,
272-
uint8_t const* _code, size_t _codeSize)
287+
uint8_t const* _code, size_t _codeSize, evmc_trace_callback _traceCallback,
288+
evmc_tracer_context* _traceContext)
273289
{
274290
m_context = _context;
275291
m_rev = _rev;
@@ -278,6 +294,8 @@ owning_bytes_ref VM::exec(evmc_context* _context, evmc_revision _rev, const evmc
278294
m_PC = 0;
279295
m_pCode = _code;
280296
m_codeSize = _codeSize;
297+
m_traceCallback = _traceCallback;
298+
m_traceContext = _traceContext;
281299

282300
// trampoline to minimize depth of call stack when calling out
283301
m_bounce = &VM::initEntry;

libaleth-interpreter/VM.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ class VM
6565
VM() = default;
6666

6767
owning_bytes_ref exec(evmc_context* _context, evmc_revision _rev, const evmc_message* _msg,
68-
uint8_t const* _code, size_t _codeSize);
68+
uint8_t const* _code, size_t _codeSize, evmc_trace_callback _traceCallback,
69+
evmc_tracer_context* _traceContext);
6970

7071
uint64_t m_io_gas = 0;
7172
private:
@@ -114,6 +115,8 @@ class VM
114115
uint64_t m_newMemSize = 0;
115116
uint64_t m_copyMemSize = 0;
116117

118+
evmc_trace_callback m_traceCallback = nullptr;
119+
evmc_tracer_context* m_traceContext = nullptr;
117120
void trace() noexcept;
118121

119122
// initialize interpreter

0 commit comments

Comments
 (0)