From 55d2a459a9193024930101c79bbf48af2eb39e2d Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 28 Aug 2017 15:30:01 +0100 Subject: [PATCH 1/5] Mark functions static in libevmasm --- libevmasm/Assembly.cpp | 4 ++-- libevmasm/Assembly.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 8c1f92965..696ab0b35 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -210,7 +210,7 @@ ostream& Assembly::streamAsm(ostream& _out, string const& _prefix, StringMap con return _out; } -Json::Value Assembly::createJsonValue(string _name, int _begin, int _end, string _value, string _jumpType) const +Json::Value Assembly::createJsonValue(string _name, int _begin, int _end, string _value, string _jumpType) { Json::Value value; value["name"] = _name; @@ -223,7 +223,7 @@ Json::Value Assembly::createJsonValue(string _name, int _begin, int _end, string return value; } -string toStringInHex(u256 _value) +string Assembly::toStringInHex(u256 _value) { std::stringstream hexStr; hexStr << hex << _value; diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index 680cb1af2..8116c2cea 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -138,7 +138,8 @@ protected: private: Json::Value streamAsmJson(std::ostream& _out, StringMap const& _sourceCodes) const; std::ostream& streamAsm(std::ostream& _out, std::string const& _prefix, StringMap const& _sourceCodes) const; - Json::Value createJsonValue(std::string _name, int _begin, int _end, std::string _value = std::string(), std::string _jumpType = std::string()) const; + static Json::Value createJsonValue(std::string _name, int _begin, int _end, std::string _value = std::string(), std::string _jumpType = std::string()); + static std::string toStringInHex(u256 _value); protected: /// 0 is reserved for exception From a535a8b06ed1b9c0c5fd41805a4fe39939755f05 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 15 Jun 2017 10:22:47 +0100 Subject: [PATCH 2/5] Split out the JSON functionality from assembly.stream() --- libevmasm/Assembly.cpp | 21 ++++--------------- libevmasm/Assembly.h | 15 ++++++++------ liblll/Compiler.cpp | 2 +- libsolidity/codegen/Compiler.h | 10 ++++++--- libsolidity/codegen/CompilerContext.h | 11 +++++++--- libsolidity/interface/AssemblyStack.cpp | 2 +- libsolidity/interface/CompilerStack.cpp | 16 ++++++++++++--- libsolidity/interface/CompilerStack.h | 8 ++++++-- libsolidity/interface/StandardCompiler.cpp | 4 ++-- solc/CommandLineInterface.cpp | 24 ++++++++++++++-------- 10 files changed, 67 insertions(+), 46 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 696ab0b35..a07226ca3 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -181,7 +181,7 @@ private: } -ostream& Assembly::streamAsm(ostream& _out, string const& _prefix, StringMap const& _sourceCodes) const +ostream& Assembly::assemblyStream(ostream& _out, string const& _prefix, StringMap const& _sourceCodes) const { Functionalizer f(_out, _prefix, _sourceCodes); @@ -199,7 +199,7 @@ ostream& Assembly::streamAsm(ostream& _out, string const& _prefix, StringMap con for (size_t i = 0; i < m_subs.size(); ++i) { _out << endl << _prefix << "sub_" << i << ": assembly {\n"; - m_subs[i]->streamAsm(_out, _prefix + " ", _sourceCodes); + m_subs[i]->assemblyStream(_out, _prefix + " ", _sourceCodes); _out << _prefix << "}" << endl; } } @@ -230,7 +230,7 @@ string Assembly::toStringInHex(u256 _value) return hexStr.str(); } -Json::Value Assembly::streamAsmJson(ostream& _out, StringMap const& _sourceCodes) const +Json::Value Assembly::assemblyJSON(StringMap const& _sourceCodes) const { Json::Value root; @@ -301,29 +301,16 @@ Json::Value Assembly::streamAsmJson(ostream& _out, StringMap const& _sourceCodes { std::stringstream hexStr; hexStr << hex << i; - data[hexStr.str()] = m_subs[i]->stream(_out, "", _sourceCodes, true); + data[hexStr.str()] = m_subs[i]->assemblyJSON(_sourceCodes); } } if (m_auxiliaryData.size() > 0) root[".auxdata"] = toHex(m_auxiliaryData); - _out << root; - return root; } -Json::Value Assembly::stream(ostream& _out, string const& _prefix, StringMap const& _sourceCodes, bool _inJsonFormat) const -{ - if (_inJsonFormat) - return streamAsmJson(_out, _sourceCodes); - else - { - streamAsm(_out, _prefix, _sourceCodes); - return Json::Value(); - } -} - AssemblyItem const& Assembly::append(AssemblyItem const& _i) { assertThrow(m_deposit >= 0, AssemblyException, ""); diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index 8116c2cea..ab8f174d3 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -120,11 +120,16 @@ public: /// If @a _enable is not set, will perform some simple peephole optimizations. Assembly& optimise(bool _enable, bool _isCreation = true, size_t _runs = 200); - Json::Value stream( + /// Create a text representation of the assembly. + std::ostream& assemblyStream( std::ostream& _out, std::string const& _prefix = "", - const StringMap &_sourceCodes = StringMap(), - bool _inJsonFormat = false + StringMap const& _sourceCodes = StringMap() + ) const; + + /// Create a JSON representation of the assembly. + Json::Value assemblyJSON( + StringMap const& _sourceCodes = StringMap() ) const; protected: @@ -136,8 +141,6 @@ protected: unsigned bytesRequired(unsigned subTagSize) const; private: - Json::Value streamAsmJson(std::ostream& _out, StringMap const& _sourceCodes) const; - std::ostream& streamAsm(std::ostream& _out, std::string const& _prefix, StringMap const& _sourceCodes) const; static Json::Value createJsonValue(std::string _name, int _begin, int _end, std::string _value = std::string(), std::string _jumpType = std::string()); static std::string toStringInHex(u256 _value); @@ -162,7 +165,7 @@ protected: inline std::ostream& operator<<(std::ostream& _out, Assembly const& _a) { - _a.stream(_out); + _a.assemblyStream(_out); return _out; } diff --git a/liblll/Compiler.cpp b/liblll/Compiler.cpp index 4ec11ca93..f9bd3ab94 100644 --- a/liblll/Compiler.cpp +++ b/liblll/Compiler.cpp @@ -76,7 +76,7 @@ std::string dev::eth::compileLLLToAsm(std::string const& _src, bool _opt, std::v auto assembly = CodeFragment::compile(_src, cs).assembly(cs); if (_opt) assembly = assembly.optimise(true); - assembly.stream(ret); + assembly.assemblyStream(ret); for (auto i: cs.treesToKill) killBigints(i); return ret.str(); diff --git a/libsolidity/codegen/Compiler.h b/libsolidity/codegen/Compiler.h index c6ee93fbd..1224ff601 100644 --- a/libsolidity/codegen/Compiler.h +++ b/libsolidity/codegen/Compiler.h @@ -60,10 +60,14 @@ public: /// @returns Only the runtime object (without constructor). eth::LinkerObject runtimeObject() const { return m_context.assembledRuntimeObject(m_runtimeSub); } /// @arg _sourceCodes is the map of input files to source code strings - /// @arg _inJsonFromat shows whether the out should be in Json format - Json::Value streamAssembly(std::ostream& _stream, StringMap const& _sourceCodes = StringMap(), bool _inJsonFormat = false) const + std::ostream& assemblyStream(std::ostream& _stream, StringMap const& _sourceCodes = StringMap()) const { - return m_context.streamAssembly(_stream, _sourceCodes, _inJsonFormat); + return m_context.assemblyStream(_stream, _sourceCodes); + } + /// @arg _sourceCodes is the map of input files to source code strings + Json::Value assemblyJSON(StringMap const& _sourceCodes = StringMap()) const + { + return m_context.assemblyJSON(_sourceCodes); } /// @returns Assembly items of the normal compiler context eth::AssemblyItems const& assemblyItems() const { return m_context.assembly().items(); } diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index 3994b0101..de79aa427 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -209,10 +209,15 @@ public: eth::Assembly& nonConstAssembly() { return *m_asm; } /// @arg _sourceCodes is the map of input files to source code strings - /// @arg _inJsonFormat shows whether the out should be in Json format - Json::Value streamAssembly(std::ostream& _stream, StringMap const& _sourceCodes = StringMap(), bool _inJsonFormat = false) const + std::ostream& assemblyStream(std::ostream& _stream, StringMap const& _sourceCodes = StringMap()) const { - return m_asm->stream(_stream, "", _sourceCodes, _inJsonFormat); + return m_asm->assemblyStream(_stream, "", _sourceCodes); + } + + /// @arg _sourceCodes is the map of input files to source code strings + Json::Value assemblyJSON(StringMap const& _sourceCodes = StringMap()) const + { + return m_asm->assemblyJSON(_sourceCodes); } eth::LinkerObject const& assembledObject() const { return m_asm->assemble(); } diff --git a/libsolidity/interface/AssemblyStack.cpp b/libsolidity/interface/AssemblyStack.cpp index 23524bb3f..025a01acc 100644 --- a/libsolidity/interface/AssemblyStack.cpp +++ b/libsolidity/interface/AssemblyStack.cpp @@ -92,7 +92,7 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine) const assembly::CodeGenerator::assemble(*m_parserResult, *m_analysisInfo, assembly); object.bytecode = make_shared(assembly.assemble()); ostringstream tmp; - assembly.stream(tmp); + assembly.assemblyStream(tmp); object.assembly = tmp.str(); return object; } diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 259694dab..4002bac32 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -347,18 +347,28 @@ eth::LinkerObject const& CompilerStack::cloneObject(string const& _contractName) return contract(_contractName).cloneObject; } -Json::Value CompilerStack::streamAssembly(ostream& _outStream, string const& _contractName, StringMap _sourceCodes, bool _inJsonFormat) const +ostream& CompilerStack::assemblyStream(ostream& _outStream, string const& _contractName, StringMap _sourceCodes) const { Contract const& currentContract = contract(_contractName); if (currentContract.compiler) - return currentContract.compiler->streamAssembly(_outStream, _sourceCodes, _inJsonFormat); + return currentContract.compiler->assemblyStream(_outStream, _sourceCodes); else { _outStream << "Contract not fully implemented" << endl; - return Json::Value(); + return _outStream; } } +/// FIXME: cache the JSON +Json::Value CompilerStack::assemblyJSON(string const& _contractName, StringMap _sourceCodes) const +{ + Contract const& currentContract = contract(_contractName); + if (currentContract.compiler) + return currentContract.compiler->assemblyJSON(_sourceCodes); + else + return Json::Value(); +} + vector CompilerStack::sourceNames() const { vector names; diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 2756e57d6..207778f03 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -192,9 +192,13 @@ public: /// Streams a verbose version of the assembly to @a _outStream. /// @arg _sourceCodes is the map of input files to source code strings - /// @arg _inJsonFromat shows whether the out should be in Json format /// Prerequisite: Successful compilation. - Json::Value streamAssembly(std::ostream& _outStream, std::string const& _contractName = "", StringMap _sourceCodes = StringMap(), bool _inJsonFormat = false) const; + std::ostream& assemblyStream(std::ostream& _outStream, std::string const& _contractName = "", StringMap _sourceCodes = StringMap()) const; + + /// @returns a JSON representation of the assembly. + /// @arg _sourceCodes is the map of input files to source code strings + /// Prerequisite: Successful compilation. + Json::Value assemblyJSON(std::string const& _contractName = "", StringMap _sourceCodes = StringMap()) const; /// @returns a JSON representing the contract ABI. /// Prerequisite: Successful call to parse or compile. diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index be823743f..c821a3416 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -401,9 +401,9 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) Json::Value evmData(Json::objectValue); // @TODO: add ir ostringstream tmp; - m_compilerStack.streamAssembly(tmp, contractName, createSourceList(_input), false); + m_compilerStack.assemblyStream(tmp, contractName, createSourceList(_input)); evmData["assembly"] = tmp.str(); - evmData["legacyAssembly"] = m_compilerStack.streamAssembly(tmp, contractName, createSourceList(_input), true); + evmData["legacyAssembly"] = m_compilerStack.assemblyJSON(contractName, createSourceList(_input)); evmData["methodIdentifiers"] = m_compilerStack.methodIdentifiers(contractName); evmData["gasEstimates"] = m_compilerStack.gasEstimates(contractName); diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 315f951e7..560dc98be 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -865,10 +865,7 @@ void CommandLineInterface::handleCombinedJSON() if (requests.count(g_strOpcodes)) contractData[g_strOpcodes] = solidity::disassemble(m_compiler->object(contractName).bytecode); if (requests.count(g_strAsm)) - { - ostringstream unused; - contractData[g_strAsm] = m_compiler->streamAssembly(unused, contractName, m_sourceCodes, true); - } + contractData[g_strAsm] = m_compiler->assemblyJSON(contractName, m_sourceCodes); if (requests.count(g_strSrcMap)) { auto map = m_compiler->sourceMapping(contractName); @@ -1152,14 +1149,25 @@ void CommandLineInterface::outputCompilationResults() { if (m_args.count(g_argOutputDir)) { - stringstream data; - m_compiler->streamAssembly(data, contract, m_sourceCodes, m_args.count(g_argAsmJson)); - createFile(m_compiler->filesystemFriendlyName(contract) + (m_args.count(g_argAsmJson) ? "_evm.json" : ".evm"), data.str()); + if (m_args.count(g_argAsmJson) + { + Json::Value ret = m_compiler->assemblyJSON(contract, m_sourceCodes); + createFile(m_compiler->filesystemFriendlyName(contract) + "_evm.json", dev::jsonPrettyPrint(ret)); + } + else + { + stringstream data; + m_compiler->assemblyStream(data, contract, m_sourceCodes); + createFile(m_compiler->filesystemFriendlyName(contract) + ".evm", data.str()); + } } else { cout << "EVM assembly:" << endl; - m_compiler->streamAssembly(cout, contract, m_sourceCodes, m_args.count(g_argAsmJson)); + if (m_args.count(g_argAsmJson) + cout << m_compiler->assemblyJSON(contract, m_sourceCodes); + else + m_compiler->assemblyStream(cout, contract, m_sourceCodes); } } From 50570c6c794eee01af64751c884fb6cb68f8dffc Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 30 Aug 2017 01:58:19 +0100 Subject: [PATCH 3/5] Do not return the stream in asssemblyStream --- libevmasm/Assembly.cpp | 4 +--- libevmasm/Assembly.h | 2 +- libsolidity/codegen/Compiler.h | 4 ++-- libsolidity/codegen/CompilerContext.h | 4 ++-- libsolidity/interface/CompilerStack.cpp | 5 ++--- libsolidity/interface/CompilerStack.h | 2 +- 6 files changed, 9 insertions(+), 12 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index a07226ca3..2203cadf5 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -181,7 +181,7 @@ private: } -ostream& Assembly::assemblyStream(ostream& _out, string const& _prefix, StringMap const& _sourceCodes) const +void Assembly::assemblyStream(ostream& _out, string const& _prefix, StringMap const& _sourceCodes) const { Functionalizer f(_out, _prefix, _sourceCodes); @@ -206,8 +206,6 @@ ostream& Assembly::assemblyStream(ostream& _out, string const& _prefix, StringMa if (m_auxiliaryData.size() > 0) _out << endl << _prefix << "auxdata: 0x" << toHex(m_auxiliaryData) << endl; - - return _out; } Json::Value Assembly::createJsonValue(string _name, int _begin, int _end, string _value, string _jumpType) diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index ab8f174d3..b7e9b354b 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -121,7 +121,7 @@ public: Assembly& optimise(bool _enable, bool _isCreation = true, size_t _runs = 200); /// Create a text representation of the assembly. - std::ostream& assemblyStream( + void assemblyStream( std::ostream& _out, std::string const& _prefix = "", StringMap const& _sourceCodes = StringMap() diff --git a/libsolidity/codegen/Compiler.h b/libsolidity/codegen/Compiler.h index 1224ff601..5233cc91f 100644 --- a/libsolidity/codegen/Compiler.h +++ b/libsolidity/codegen/Compiler.h @@ -60,9 +60,9 @@ public: /// @returns Only the runtime object (without constructor). eth::LinkerObject runtimeObject() const { return m_context.assembledRuntimeObject(m_runtimeSub); } /// @arg _sourceCodes is the map of input files to source code strings - std::ostream& assemblyStream(std::ostream& _stream, StringMap const& _sourceCodes = StringMap()) const + void assemblyStream(std::ostream& _stream, StringMap const& _sourceCodes = StringMap()) const { - return m_context.assemblyStream(_stream, _sourceCodes); + m_context.assemblyStream(_stream, _sourceCodes); } /// @arg _sourceCodes is the map of input files to source code strings Json::Value assemblyJSON(StringMap const& _sourceCodes = StringMap()) const diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index de79aa427..47d4edde3 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -209,9 +209,9 @@ public: eth::Assembly& nonConstAssembly() { return *m_asm; } /// @arg _sourceCodes is the map of input files to source code strings - std::ostream& assemblyStream(std::ostream& _stream, StringMap const& _sourceCodes = StringMap()) const + void assemblyStream(std::ostream& _stream, StringMap const& _sourceCodes = StringMap()) const { - return m_asm->assemblyStream(_stream, "", _sourceCodes); + m_asm->assemblyStream(_stream, "", _sourceCodes); } /// @arg _sourceCodes is the map of input files to source code strings diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 4002bac32..5f62bb03f 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -347,15 +347,14 @@ eth::LinkerObject const& CompilerStack::cloneObject(string const& _contractName) return contract(_contractName).cloneObject; } -ostream& CompilerStack::assemblyStream(ostream& _outStream, string const& _contractName, StringMap _sourceCodes) const +void CompilerStack::assemblyStream(ostream& _outStream, string const& _contractName, StringMap _sourceCodes) const { Contract const& currentContract = contract(_contractName); if (currentContract.compiler) - return currentContract.compiler->assemblyStream(_outStream, _sourceCodes); + currentContract.compiler->assemblyStream(_outStream, _sourceCodes); else { _outStream << "Contract not fully implemented" << endl; - return _outStream; } } diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 207778f03..2f1b9bb36 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -193,7 +193,7 @@ public: /// Streams a verbose version of the assembly to @a _outStream. /// @arg _sourceCodes is the map of input files to source code strings /// Prerequisite: Successful compilation. - std::ostream& assemblyStream(std::ostream& _outStream, std::string const& _contractName = "", StringMap _sourceCodes = StringMap()) const; + void assemblyStream(std::ostream& _outStream, std::string const& _contractName = "", StringMap _sourceCodes = StringMap()) const; /// @returns a JSON representation of the assembly. /// @arg _sourceCodes is the map of input files to source code strings From bbfb16cf5ce903150bc3a141ac50553d8bf6d346 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 30 Aug 2017 02:17:15 +0100 Subject: [PATCH 4/5] Introduce assemblyString --- libevmasm/Assembly.cpp | 7 +++++++ libevmasm/Assembly.h | 3 +++ liblll/Compiler.cpp | 5 ++--- libsolidity/codegen/Compiler.h | 4 ++-- libsolidity/codegen/CompilerContext.h | 4 ++-- libsolidity/interface/AssemblyStack.cpp | 4 +--- libsolidity/interface/CompilerStack.cpp | 9 ++++----- libsolidity/interface/CompilerStack.h | 4 ++-- libsolidity/interface/StandardCompiler.cpp | 4 +--- solc/CommandLineInterface.cpp | 7 +++---- 10 files changed, 27 insertions(+), 24 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 2203cadf5..6b4bb52b4 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -208,6 +208,13 @@ void Assembly::assemblyStream(ostream& _out, string const& _prefix, StringMap co _out << endl << _prefix << "auxdata: 0x" << toHex(m_auxiliaryData) << endl; } +string Assembly::assemblyString(StringMap const& _sourceCodes) const +{ + ostringstream tmp; + assemblyStream(tmp, "", _sourceCodes); + return tmp.str(); +} + Json::Value Assembly::createJsonValue(string _name, int _begin, int _end, string _value, string _jumpType) { Json::Value value; diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index b7e9b354b..cbdd71bcf 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -121,6 +121,9 @@ public: Assembly& optimise(bool _enable, bool _isCreation = true, size_t _runs = 200); /// Create a text representation of the assembly. + std::string assemblyString( + StringMap const& _sourceCodes = StringMap() + ) const; void assemblyStream( std::ostream& _out, std::string const& _prefix = "", diff --git a/liblll/Compiler.cpp b/liblll/Compiler.cpp index f9bd3ab94..b69675aab 100644 --- a/liblll/Compiler.cpp +++ b/liblll/Compiler.cpp @@ -72,14 +72,13 @@ std::string dev::eth::compileLLLToAsm(std::string const& _src, bool _opt, std::v { CompilerState cs; cs.populateStandard(); - stringstream ret; auto assembly = CodeFragment::compile(_src, cs).assembly(cs); if (_opt) assembly = assembly.optimise(true); - assembly.assemblyStream(ret); + string ret = assembly.assemblyString(); for (auto i: cs.treesToKill) killBigints(i); - return ret.str(); + return ret; } catch (Exception const& _e) { diff --git a/libsolidity/codegen/Compiler.h b/libsolidity/codegen/Compiler.h index 5233cc91f..06654486a 100644 --- a/libsolidity/codegen/Compiler.h +++ b/libsolidity/codegen/Compiler.h @@ -60,9 +60,9 @@ public: /// @returns Only the runtime object (without constructor). eth::LinkerObject runtimeObject() const { return m_context.assembledRuntimeObject(m_runtimeSub); } /// @arg _sourceCodes is the map of input files to source code strings - void assemblyStream(std::ostream& _stream, StringMap const& _sourceCodes = StringMap()) const + std::string assemblyString(StringMap const& _sourceCodes = StringMap()) const { - m_context.assemblyStream(_stream, _sourceCodes); + return m_context.assemblyString(_sourceCodes); } /// @arg _sourceCodes is the map of input files to source code strings Json::Value assemblyJSON(StringMap const& _sourceCodes = StringMap()) const diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index 47d4edde3..5116585e7 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -209,9 +209,9 @@ public: eth::Assembly& nonConstAssembly() { return *m_asm; } /// @arg _sourceCodes is the map of input files to source code strings - void assemblyStream(std::ostream& _stream, StringMap const& _sourceCodes = StringMap()) const + std::string assemblyString(StringMap const& _sourceCodes = StringMap()) const { - m_asm->assemblyStream(_stream, "", _sourceCodes); + return m_asm->assemblyString(_sourceCodes); } /// @arg _sourceCodes is the map of input files to source code strings diff --git a/libsolidity/interface/AssemblyStack.cpp b/libsolidity/interface/AssemblyStack.cpp index 025a01acc..504ad92c4 100644 --- a/libsolidity/interface/AssemblyStack.cpp +++ b/libsolidity/interface/AssemblyStack.cpp @@ -91,9 +91,7 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine) const eth::Assembly assembly; assembly::CodeGenerator::assemble(*m_parserResult, *m_analysisInfo, assembly); object.bytecode = make_shared(assembly.assemble()); - ostringstream tmp; - assembly.assemblyStream(tmp); - object.assembly = tmp.str(); + object.assembly = assembly.assemblyString(); return object; } case Machine::EVM15: diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 5f62bb03f..41bbf687c 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -347,15 +347,14 @@ eth::LinkerObject const& CompilerStack::cloneObject(string const& _contractName) return contract(_contractName).cloneObject; } -void CompilerStack::assemblyStream(ostream& _outStream, string const& _contractName, StringMap _sourceCodes) const +/// FIXME: cache this string +string CompilerStack::assemblyString(string const& _contractName, StringMap _sourceCodes) const { Contract const& currentContract = contract(_contractName); if (currentContract.compiler) - currentContract.compiler->assemblyStream(_outStream, _sourceCodes); + return currentContract.compiler->assemblyString(_sourceCodes); else - { - _outStream << "Contract not fully implemented" << endl; - } + return string(); } /// FIXME: cache the JSON diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 2f1b9bb36..f1bbae47e 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -190,10 +190,10 @@ public: /// if the contract does not (yet) have bytecode. std::string const* runtimeSourceMapping(std::string const& _contractName = "") const; - /// Streams a verbose version of the assembly to @a _outStream. + /// @return a verbose text representation of the assembly. /// @arg _sourceCodes is the map of input files to source code strings /// Prerequisite: Successful compilation. - void assemblyStream(std::ostream& _outStream, std::string const& _contractName = "", StringMap _sourceCodes = StringMap()) const; + std::string assemblyString(std::string const& _contractName = "", StringMap _sourceCodes = StringMap()) const; /// @returns a JSON representation of the assembly. /// @arg _sourceCodes is the map of input files to source code strings diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index c821a3416..b4fbbef9b 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -400,9 +400,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) // EVM Json::Value evmData(Json::objectValue); // @TODO: add ir - ostringstream tmp; - m_compilerStack.assemblyStream(tmp, contractName, createSourceList(_input)); - evmData["assembly"] = tmp.str(); + evmData["assembly"] = m_compilerStack.assemblyString(contractName, createSourceList(_input)); evmData["legacyAssembly"] = m_compilerStack.assemblyJSON(contractName, createSourceList(_input)); evmData["methodIdentifiers"] = m_compilerStack.methodIdentifiers(contractName); evmData["gasEstimates"] = m_compilerStack.gasEstimates(contractName); diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 560dc98be..32c61585d 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -1156,9 +1156,8 @@ void CommandLineInterface::outputCompilationResults() } else { - stringstream data; - m_compiler->assemblyStream(data, contract, m_sourceCodes); - createFile(m_compiler->filesystemFriendlyName(contract) + ".evm", data.str()); + string ret = m_compiler->assemblyString(contract, m_sourceCodes); + createFile(m_compiler->filesystemFriendlyName(contract) + ".evm", ret)); } } else @@ -1167,7 +1166,7 @@ void CommandLineInterface::outputCompilationResults() if (m_args.count(g_argAsmJson) cout << m_compiler->assemblyJSON(contract, m_sourceCodes); else - m_compiler->assemblyStream(cout, contract, m_sourceCodes); + cout << m_compiler->assemblyString(contract, m_sourceCodes); } } From bd6510d99a503ddbdbfaa9bd459f020215f8a028 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 11 Sep 2017 15:18:56 +0100 Subject: [PATCH 5/5] Simplify assembly printing in CLI --- solc/CommandLineInterface.cpp | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 32c61585d..e6d8776bf 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -1147,26 +1147,19 @@ void CommandLineInterface::outputCompilationResults() // do we need EVM assembly? if (m_args.count(g_argAsm) || m_args.count(g_argAsmJson)) { + string ret; + if (m_args.count(g_argAsmJson)) + ret = dev::jsonPrettyPrint(m_compiler->assemblyJSON(contract, m_sourceCodes)); + else + ret = m_compiler->assemblyString(contract, m_sourceCodes); + if (m_args.count(g_argOutputDir)) { - if (m_args.count(g_argAsmJson) - { - Json::Value ret = m_compiler->assemblyJSON(contract, m_sourceCodes); - createFile(m_compiler->filesystemFriendlyName(contract) + "_evm.json", dev::jsonPrettyPrint(ret)); - } - else - { - string ret = m_compiler->assemblyString(contract, m_sourceCodes); - createFile(m_compiler->filesystemFriendlyName(contract) + ".evm", ret)); - } + createFile(m_compiler->filesystemFriendlyName(contract) + (m_args.count(g_argAsmJson) ? "_evm.json" : ".evm"), ret); } else { - cout << "EVM assembly:" << endl; - if (m_args.count(g_argAsmJson) - cout << m_compiler->assemblyJSON(contract, m_sourceCodes); - else - cout << m_compiler->assemblyString(contract, m_sourceCodes); + cout << "EVM assembly:" << endl << ret << endl; } }