|
@ -21,6 +21,8 @@ |
|
|
|
|
|
|
|
|
#include "Assembly.h" |
|
|
#include "Assembly.h" |
|
|
|
|
|
|
|
|
|
|
|
#include <fstream> |
|
|
|
|
|
|
|
|
#include <libdevcore/Log.h> |
|
|
#include <libdevcore/Log.h> |
|
|
|
|
|
|
|
|
using namespace std; |
|
|
using namespace std; |
|
@ -171,49 +173,74 @@ ostream& dev::eth::operator<<(ostream& _out, AssemblyItemsConstRef _i) |
|
|
return _out; |
|
|
return _out; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
ostream& Assembly::streamRLP(ostream& _out, string const& _prefix, StringMap _sourceCodes) const |
|
|
string Assembly::getLocationFromSources(StringMap const& _sourceCodes, SourceLocation const& _location) const |
|
|
|
|
|
{ |
|
|
|
|
|
if (_location.isEmpty() || _sourceCodes.empty() || _location.start >= _location.end || _location.start < 0) |
|
|
|
|
|
return ""; |
|
|
|
|
|
|
|
|
|
|
|
auto it = _sourceCodes.find(*_location.sourceName); |
|
|
|
|
|
if (it == _sourceCodes.end()) |
|
|
|
|
|
return ""; |
|
|
|
|
|
|
|
|
|
|
|
string toReturn = it->second; |
|
|
|
|
|
if (_location.start >= (int)toReturn.size()) |
|
|
|
|
|
return ""; |
|
|
|
|
|
|
|
|
|
|
|
toReturn = toReturn.substr(_location.start, _location.end - _location.start); |
|
|
|
|
|
auto newLinePos = toReturn.find_first_of("\n"); |
|
|
|
|
|
if (newLinePos != string::npos && newLinePos != toReturn.size() - 1) |
|
|
|
|
|
toReturn = toReturn.substr(0, newLinePos) + "..."; |
|
|
|
|
|
|
|
|
|
|
|
return move(toReturn); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ostream& Assembly::streamRLP(ostream& _out, string const& _prefix, StringMap const& _sourceCodes) const |
|
|
{ |
|
|
{ |
|
|
(void)_sourceCodes; |
|
|
|
|
|
_out << _prefix << ".code:" << endl; |
|
|
_out << _prefix << ".code:" << endl; |
|
|
for (AssemblyItem const& i: m_items) |
|
|
for (AssemblyItem const& i: m_items) |
|
|
|
|
|
{ |
|
|
|
|
|
string sourceLine = getLocationFromSources(_sourceCodes, i.getLocation()); |
|
|
|
|
|
_out << _prefix; |
|
|
switch (i.m_type) |
|
|
switch (i.m_type) |
|
|
{ |
|
|
{ |
|
|
case Operation: |
|
|
case Operation: |
|
|
_out << _prefix << " " << instructionInfo((Instruction)(byte)i.m_data).name << endl; |
|
|
_out << " " << instructionInfo((Instruction)(byte)i.m_data).name; |
|
|
break; |
|
|
break; |
|
|
case Push: |
|
|
case Push: |
|
|
_out << _prefix << " PUSH " << i.m_data << endl; |
|
|
_out << " PUSH " << i.m_data; |
|
|
break; |
|
|
break; |
|
|
case PushString: |
|
|
case PushString: |
|
|
_out << _prefix << " PUSH \"" << m_strings.at((h256)i.m_data) << "\"" << endl; |
|
|
_out << " PUSH \"" << m_strings.at((h256)i.m_data) << "\""; |
|
|
break; |
|
|
break; |
|
|
case PushTag: |
|
|
case PushTag: |
|
|
_out << _prefix << " PUSH [tag" << i.m_data << "]" << endl; |
|
|
_out << " PUSH [tag" << i.m_data << "]"; |
|
|
break; |
|
|
break; |
|
|
case PushSub: |
|
|
case PushSub: |
|
|
_out << _prefix << " PUSH [$" << h256(i.m_data).abridged() << "]" << endl; |
|
|
_out << " PUSH [$" << h256(i.m_data).abridged() << "]"; |
|
|
break; |
|
|
break; |
|
|
case PushSubSize: |
|
|
case PushSubSize: |
|
|
_out << _prefix << " PUSH #[$" << h256(i.m_data).abridged() << "]" << endl; |
|
|
_out << " PUSH #[$" << h256(i.m_data).abridged() << "]"; |
|
|
break; |
|
|
break; |
|
|
case PushProgramSize: |
|
|
case PushProgramSize: |
|
|
_out << _prefix << " PUSHSIZE" << endl; |
|
|
_out << " PUSHSIZE"; |
|
|
break; |
|
|
break; |
|
|
case Tag: |
|
|
case Tag: |
|
|
_out << _prefix << "tag" << i.m_data << ": " << endl << _prefix << " JUMPDEST" << endl; |
|
|
_out << "tag" << i.m_data << ": " << endl << _prefix << " JUMPDEST"; |
|
|
break; |
|
|
break; |
|
|
case PushData: |
|
|
case PushData: |
|
|
_out << _prefix << " PUSH [" << hex << (unsigned)i.m_data << "]" << endl; |
|
|
_out << " PUSH [" << hex << (unsigned)i.m_data << "]"; |
|
|
break; |
|
|
break; |
|
|
case NoOptimizeBegin: |
|
|
case NoOptimizeBegin: |
|
|
_out << _prefix << "DoNotOptimze{{" << endl; |
|
|
_out << "DoNotOptimze{{"; |
|
|
break; |
|
|
break; |
|
|
case NoOptimizeEnd: |
|
|
case NoOptimizeEnd: |
|
|
_out << _prefix << "DoNotOptimze}}" << endl; |
|
|
_out << "DoNotOptimze}}"; |
|
|
break; |
|
|
break; |
|
|
default: |
|
|
default: |
|
|
BOOST_THROW_EXCEPTION(InvalidOpcode()); |
|
|
BOOST_THROW_EXCEPTION(InvalidOpcode()); |
|
|
} |
|
|
} |
|
|
|
|
|
_out << string(20, ' ') << sourceLine << endl; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (!m_data.empty() || !m_subs.empty()) |
|
|
if (!m_data.empty() || !m_subs.empty()) |
|
|
{ |
|
|
{ |
|
|