2222
2323namespace
2424{
25+ evmc_trace_callback g_traceCallback = nullptr ;
26+ evmc_tracer_context* g_traceContext = nullptr ;
27+
2528void destroy (evmc_instance* _instance)
2629{
2730 (void )_instance;
@@ -33,7 +36,7 @@ void delete_output(const evmc_result* result)
3336}
3437
3538evmc_result execute (evmc_instance* _instance, evmc_context* _context, evmc_revision _rev,
36- const evmc_message* _msg, uint8_t const * _code, size_t _codeSize) noexcept
39+ evmc_message const * _msg, uint8_t const * _code, size_t _codeSize) noexcept
3740{
3841 (void )_instance;
3942 std::unique_ptr<dev::eth::VM> vm{new dev::eth::VM};
@@ -82,28 +85,47 @@ evmc_result execute(evmc_instance* _instance, evmc_context* _context, evmc_revis
8285
8386 return result;
8487}
88+
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+ }
8595} // namespace
8696
8797extern " C" evmc_instance* evmc_create_interpreter () noexcept
8898{
8999 // TODO: Allow creating multiple instances with different configurations.
90100 static evmc_instance s_instance{
91- EVMC_ABI_VERSION,
92- " interpreter" ,
93- aleth_get_buildinfo ()->project_version ,
94- ::destroy,
95- ::execute,
96- nullptr , // set_tracer
101+ EVMC_ABI_VERSION, " interpreter" , aleth_get_buildinfo ()->project_version , ::destroy,
102+ ::execute, ::setTracer,
97103 nullptr , // set_option
98104 };
99105 return &s_instance;
100106}
101107
102-
103108namespace dev
104109{
105110namespace eth
106111{
112+ void VM::trace () noexcept
113+ {
114+ if (g_traceCallback)
115+ {
116+ auto const & metrics = c_metrics[static_cast <size_t >(m_OP)];
117+ evmc_uint256be topStackItem;
118+ evmc_uint256be const * pushedStackItem = nullptr ;
119+ if (metrics.num_stack_returned_items == 1 )
120+ {
121+ topStackItem = toEvmC (m_SPP[0 ]);
122+ pushedStackItem = &topStackItem;
123+ }
124+ g_traceCallback (g_traceContext, m_PC, EVMC_SUCCESS, m_io_gas, m_stackEnd - m_SPP,
125+ pushedStackItem, m_mem.size (), 0 , 0 , nullptr );
126+ }
127+ }
128+
107129uint64_t VM::memNeed (u256 _offset, u256 _size)
108130{
109131 return toInt63 (_size ? u512 (_offset) + _size : u512 (0 ));
@@ -397,6 +419,7 @@ void VM::interpretCases()
397419 updateIOGas ();
398420
399421 m_SPP[0 ] = (u256)*(h256 const *)(m_mem.data () + (unsigned )m_SP[0 ]);
422+ trace ();
400423 }
401424 NEXT
402425
@@ -407,6 +430,7 @@ void VM::interpretCases()
407430 updateIOGas ();
408431
409432 *(h256*)&m_mem[(unsigned )m_SP[0 ]] = (h256)m_SP[1 ];
433+ trace ();
410434 }
411435 NEXT
412436
@@ -1155,11 +1179,14 @@ void VM::interpretCases()
11551179 // get val at two-byte offset into const pool and advance pc by one-byte remainder
11561180 TRACE_OP (2 , m_PC, m_OP);
11571181 unsigned off;
1158- ++m_PC;
1159- off = m_code[m_PC++] << 8 ;
1160- off |= m_code[m_PC++];
1161- m_PC += m_code[m_PC];
1182+ uint64_t pc = m_PC;
1183+ ++pc;
1184+ off = m_code[pc++] << 8 ;
1185+ off |= m_code[pc++];
1186+ pc += m_code[pc];
11621187 m_SPP[0 ] = m_pool[off];
1188+ trace ();
1189+ m_PC = pc;
11631190 TRACE_VAL (2 , " Retrieved pooled const" , m_SPP[0 ]);
11641191#else
11651192 throwBadInstruction ();
@@ -1171,9 +1198,9 @@ void VM::interpretCases()
11711198 {
11721199 ON_OP ();
11731200 updateIOGas ();
1174- ++ m_PC;
1175- m_SPP[ 0 ] = m_code[m_PC] ;
1176- ++ m_PC;
1201+ m_SPP[ 0 ] = m_code[ m_PC + 1 ] ;
1202+ trace () ;
1203+ m_PC += 2 ;
11771204 }
11781205 CONTINUE
11791206
@@ -1219,6 +1246,8 @@ void VM::interpretCases()
12191246 // bytes to handle "out of code" push data here.
12201247 for (++m_PC; numBytes--; ++m_PC)
12211248 m_SPP[0 ] = (m_SPP[0 ] << 8 ) | m_code[m_PC];
1249+
1250+ trace ();
12221251 }
12231252 CONTINUE
12241253
@@ -1347,6 +1376,7 @@ void VM::interpretCases()
13471376
13481377 updateSSGas ();
13491378 updateIOGas ();
1379+ trace ();
13501380
13511381 evmc_uint256be key = toEvmC (m_SP[0 ]);
13521382 evmc_uint256be value = toEvmC (m_SP[1 ]);
0 commit comments