diff --git a/libevmcore/Assembly.cpp b/libevmcore/Assembly.cpp index 0a568cbfb..7f6a16116 100644 --- a/libevmcore/Assembly.cpp +++ b/libevmcore/Assembly.cpp @@ -21,6 +21,8 @@ #include "Assembly.h" +#include + #include using namespace std; @@ -171,49 +173,74 @@ ostream& dev::eth::operator<<(ostream& _out, AssemblyItemsConstRef _i) 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; for (AssemblyItem const& i: m_items) + { + string sourceLine = getLocationFromSources(_sourceCodes, i.getLocation()); + _out << _prefix; switch (i.m_type) { case Operation: - _out << _prefix << " " << instructionInfo((Instruction)(byte)i.m_data).name << endl; + _out << " " << instructionInfo((Instruction)(byte)i.m_data).name; break; case Push: - _out << _prefix << " PUSH " << i.m_data << endl; + _out << " PUSH " << i.m_data; break; case PushString: - _out << _prefix << " PUSH \"" << m_strings.at((h256)i.m_data) << "\"" << endl; + _out << " PUSH \"" << m_strings.at((h256)i.m_data) << "\""; break; case PushTag: - _out << _prefix << " PUSH [tag" << i.m_data << "]" << endl; + _out << " PUSH [tag" << i.m_data << "]"; break; case PushSub: - _out << _prefix << " PUSH [$" << h256(i.m_data).abridged() << "]" << endl; + _out << " PUSH [$" << h256(i.m_data).abridged() << "]"; break; case PushSubSize: - _out << _prefix << " PUSH #[$" << h256(i.m_data).abridged() << "]" << endl; + _out << " PUSH #[$" << h256(i.m_data).abridged() << "]"; break; case PushProgramSize: - _out << _prefix << " PUSHSIZE" << endl; + _out << " PUSHSIZE"; break; case Tag: - _out << _prefix << "tag" << i.m_data << ": " << endl << _prefix << " JUMPDEST" << endl; + _out << "tag" << i.m_data << ": " << endl << _prefix << " JUMPDEST"; break; case PushData: - _out << _prefix << " PUSH [" << hex << (unsigned)i.m_data << "]" << endl; + _out << " PUSH [" << hex << (unsigned)i.m_data << "]"; break; case NoOptimizeBegin: - _out << _prefix << "DoNotOptimze{{" << endl; + _out << "DoNotOptimze{{"; break; case NoOptimizeEnd: - _out << _prefix << "DoNotOptimze}}" << endl; + _out << "DoNotOptimze}}"; break; default: BOOST_THROW_EXCEPTION(InvalidOpcode()); } + _out << string(20, ' ') << sourceLine << endl; + } if (!m_data.empty() || !m_subs.empty()) { diff --git a/libevmcore/Assembly.h b/libevmcore/Assembly.h index 8bab175a8..bd2c87f4c 100644 --- a/libevmcore/Assembly.h +++ b/libevmcore/Assembly.h @@ -121,9 +121,10 @@ public: bytes assemble() const; Assembly& optimise(bool _enable); - std::ostream& streamRLP(std::ostream& _out, std::string const& _prefix = "", StringMap _sourceCodes = StringMap()) const; + std::ostream& streamRLP(std::ostream& _out, std::string const& _prefix = "", const StringMap &_sourceCodes = StringMap()) const; -private: +protected: + std::string getLocationFromSources(const StringMap &_sourceCodes, const SourceLocation &_location) const; void donePath() { if (m_totalDeposit != INT_MAX && m_totalDeposit != m_deposit) BOOST_THROW_EXCEPTION(InvalidDeposit()); } unsigned bytesRequired() const; diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index db12231a7..08acb5ebd 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -424,13 +424,13 @@ void CommandLineInterface::actOnInput() if (outputToStdout(choice)) { cout << "EVM assembly:" << endl; - m_compiler->streamAssembly(cout, contract); + m_compiler->streamAssembly(cout, contract, m_sourceCodes); } if (outputToFile(choice)) { ofstream outFile(contract + ".evm"); - m_compiler->streamAssembly(outFile, contract); + m_compiler->streamAssembly(outFile, contract, m_sourceCodes); outFile.close(); } }