Browse Source

Instruction iterator.

cl-refactor
chriseth 10 years ago
parent
commit
9e407d80bc
  1. 42
      libevmcore/Instruction.cpp
  2. 4
      libevmcore/Instruction.h

42
libevmcore/Instruction.cpp

@ -21,6 +21,7 @@
#include "Instruction.h" #include "Instruction.h"
#include <functional>
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#include <libdevcore/CommonIO.h> #include <libdevcore/CommonIO.h>
#include <libdevcore/Log.h> #include <libdevcore/Log.h>
@ -294,27 +295,42 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo =
{ Instruction::SUICIDE, { "SUICIDE", 0, 1, 0, true, ZeroTier } } { Instruction::SUICIDE, { "SUICIDE", 0, 1, 0, true, ZeroTier } }
}; };
string dev::eth::disassemble(bytes const& _mem) void dev::eth::eachInstruction(
bytes const& _mem,
function<void(Instruction,u256 const&)> const& _onInstruction
)
{ {
stringstream ret;
unsigned numerics = 0;
for (auto it = _mem.begin(); it != _mem.end(); ++it) for (auto it = _mem.begin(); it != _mem.end(); ++it)
{ {
byte n = *it; Instruction instr = Instruction(*it);
auto iit = c_instructionInfo.find((Instruction)n); size_t additional = 0;
if (numerics || iit == c_instructionInfo.end() || (byte)iit->first != n) // not an instruction or expecting an argument... if (isValidInstruction(instr))
additional = instructionInfo(instr).additional;
u256 data;
for (size_t i = 0; i < additional; ++i)
{ {
if (numerics) data <<= 8;
numerics--; if (it != _mem.end() && ++it != _mem.end())
ret << "0x" << hex << (int)n << " "; data |= *it;
}
_onInstruction(instr, data);
} }
}
string dev::eth::disassemble(bytes const& _mem)
{
stringstream ret;
eachInstruction(_mem, [&](Instruction _instr, u256 const& _data) {
if (!isValidInstruction(_instr))
ret << "0x" << hex << int(_instr) << " ";
else else
{ {
auto const& ii = iit->second; InstructionInfo info = instructionInfo(_instr);
ret << ii.name << " "; ret << info.name << " ";
numerics = ii.additional; if (info.additional)
} ret << "0x" << hex << _data << " ";
} }
});
return ret.str(); return ret.str();
} }

4
libevmcore/Instruction.h

@ -21,6 +21,7 @@
#pragma once #pragma once
#include <functional>
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#include <libdevcore/Assertions.h> #include <libdevcore/Assertions.h>
#include <libevmcore/Exceptions.h> #include <libevmcore/Exceptions.h>
@ -253,6 +254,9 @@ bool isValidInstruction(Instruction _inst);
/// Convert from string mnemonic to Instruction type. /// Convert from string mnemonic to Instruction type.
extern const std::map<std::string, Instruction> c_instructions; extern const std::map<std::string, Instruction> c_instructions;
/// Iterate through EVM code and call a function on each instruction.
void eachInstruction(bytes const& _mem, std::function<void(Instruction,u256 const&)> const& _onInstruction);
/// Convert from EVM code to simple EVM assembly language. /// Convert from EVM code to simple EVM assembly language.
std::string disassemble(bytes const& _mem); std::string disassemble(bytes const& _mem);

Loading…
Cancel
Save