diff options
| author | chriseth <c@ethdev.com> | 2016-03-30 20:42:05 +0800 |
|---|---|---|
| committer | chriseth <c@ethdev.com> | 2016-03-30 20:42:05 +0800 |
| commit | 9ca29aa508a25b5ccd9261ab7fd441df27d7da5f (patch) | |
| tree | daca1d62b8253827bf8086dba3bd8679404a8660 /solc | |
| parent | 8236732e9a5d2535afd3a3573a70d5aab3da3efe (diff) | |
| parent | b336f6261c2373cc769bcafb0466a251576f3fdd (diff) | |
| download | dexon-solidity-9ca29aa508a25b5ccd9261ab7fd441df27d7da5f.tar dexon-solidity-9ca29aa508a25b5ccd9261ab7fd441df27d7da5f.tar.gz dexon-solidity-9ca29aa508a25b5ccd9261ab7fd441df27d7da5f.tar.bz2 dexon-solidity-9ca29aa508a25b5ccd9261ab7fd441df27d7da5f.tar.lz dexon-solidity-9ca29aa508a25b5ccd9261ab7fd441df27d7da5f.tar.xz dexon-solidity-9ca29aa508a25b5ccd9261ab7fd441df27d7da5f.tar.zst dexon-solidity-9ca29aa508a25b5ccd9261ab7fd441df27d7da5f.zip | |
Merge pull request #430 from chriseth/assembly
Inline Assembly
Diffstat (limited to 'solc')
| -rw-r--r-- | solc/CommandLineInterface.cpp | 61 | ||||
| -rw-r--r-- | solc/CommandLineInterface.h | 10 | ||||
| -rw-r--r-- | solc/jsonCompiler.cpp | 18 |
3 files changed, 78 insertions, 11 deletions
diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 499b1f7a..a302e024 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -45,6 +45,7 @@ #include <libsolidity/interface/CompilerStack.h> #include <libsolidity/interface/SourceReferenceFormatter.h> #include <libsolidity/interface/GasEstimator.h> +#include <libsolidity/inlineasm/AsmParser.h> #include <libsolidity/formal/Why3Translator.h> using namespace std; @@ -431,6 +432,10 @@ Allowed options)", ) (g_argGas.c_str(), "Print an estimate of the maximal gas usage for each function.") ( + "assemble", + "Switch to assembly mode, ignoring all options and assumes input is assembly." + ) + ( "link", "Switch to linker mode, ignoring all options apart from --libraries " "and modify binaries in place." @@ -509,6 +514,12 @@ bool CommandLineInterface::processInput() if (!parseLibraryOption(library)) return false; + if (m_args.count("assemble")) + { + // switch to assembly mode + m_onlyAssemble = true; + return assemble(); + } if (m_args.count("link")) { // switch to linker mode @@ -574,6 +585,7 @@ bool CommandLineInterface::processInput() }; m_compiler.reset(new CompilerStack(m_args.count(g_argAddStandard) > 0, fileReader)); + auto scannerFromSourceName = [&](string const& _sourceName) -> solidity::Scanner const& { return m_compiler->scanner(_sourceName); }; try { for (auto const& sourceCode: m_sourceCodes) @@ -593,7 +605,8 @@ bool CommandLineInterface::processInput() SourceReferenceFormatter::printExceptionInformation( cerr, *error, - (error->type() == Error::Type::Warning) ? "Warning" : "Error", *m_compiler + (error->type() == Error::Type::Warning) ? "Warning" : "Error", + scannerFromSourceName ); if (!successful) @@ -601,7 +614,7 @@ bool CommandLineInterface::processInput() } catch (CompilerError const& _exception) { - SourceReferenceFormatter::printExceptionInformation(cerr, _exception, "Compiler error", *m_compiler); + SourceReferenceFormatter::printExceptionInformation(cerr, _exception, "Compiler error", scannerFromSourceName); return false; } catch (InternalCompilerError const& _exception) @@ -615,7 +628,7 @@ bool CommandLineInterface::processInput() if (_error.type() == Error::Type::DocstringParsingError) cerr << "Documentation parsing error: " << *boost::get_error_info<errinfo_comment>(_error) << endl; else - SourceReferenceFormatter::printExceptionInformation(cerr, _error, _error.typeName(), *m_compiler); + SourceReferenceFormatter::printExceptionInformation(cerr, _error, _error.typeName(), scannerFromSourceName); return false; } @@ -759,7 +772,9 @@ void CommandLineInterface::handleAst(string const& _argStr) void CommandLineInterface::actOnInput() { - if (m_onlyLink) + if (m_onlyAssemble) + outputAssembly(); + else if (m_onlyLink) writeLinkedFiles(); else outputCompilationResults(); @@ -812,6 +827,44 @@ void CommandLineInterface::writeLinkedFiles() writeFile(src.first, src.second); } +bool CommandLineInterface::assemble() +{ + //@TODO later, we will use the convenience interface and should also remove the include above + bool successful = true; + map<string, shared_ptr<Scanner>> scanners; + for (auto const& src: m_sourceCodes) + { + auto scanner = make_shared<Scanner>(CharStream(src.second), src.first); + scanners[src.first] = scanner; + if (!m_assemblyStacks[src.first].parse(scanner)) + successful = false; + else + //@TODO we should not just throw away the result here + m_assemblyStacks[src.first].assemble(); + } + for (auto const& stack: m_assemblyStacks) + for (auto const& error: stack.second.errors()) + SourceReferenceFormatter::printExceptionInformation( + cerr, + *error, + (error->type() == Error::Type::Warning) ? "Warning" : "Error", + [&](string const& _source) -> Scanner const& { return *scanners.at(_source); } + ); + + return successful; +} + +void CommandLineInterface::outputAssembly() +{ + for (auto const& src: m_sourceCodes) + { + cout << endl << "======= " << src.first << " =======" << endl; + eth::Assembly assembly = m_assemblyStacks[src.first].assemble(); + cout << assembly.assemble().toHex() << endl; + cout << assembly.out(); + } +} + void CommandLineInterface::outputCompilationResults() { handleCombinedJSON(); diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index d288b5c1..52854bac 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -21,10 +21,11 @@ */ #pragma once -#include <libsolidity/interface/CompilerStack.h> #include <memory> #include <boost/program_options.hpp> #include <boost/filesystem/path.hpp> +#include <libsolidity/interface/CompilerStack.h> +#include <libsolidity/inlineasm/AsmStack.h> namespace dev { @@ -50,6 +51,10 @@ private: bool link(); void writeLinkedFiles(); + /// Parse assembly input. + bool assemble(); + void outputAssembly(); + void outputCompilationResults(); void handleCombinedJSON(); @@ -73,6 +78,7 @@ private: /// @arg _data to be written void createFile(std::string const& _fileName, std::string const& _data); + bool m_onlyAssemble = false; bool m_onlyLink = false; /// Compiler arguments variable map @@ -87,6 +93,8 @@ private: std::map<std::string, h160> m_libraries; /// Solidity compiler stack std::unique_ptr<dev::solidity::CompilerStack> m_compiler; + /// Assembly stacks for assembly-only mode + std::map<std::string, assembly::InlineAssemblyStack> m_assemblyStacks; }; } diff --git a/solc/jsonCompiler.cpp b/solc/jsonCompiler.cpp index b5efa94d..c6b40fdc 100644 --- a/solc/jsonCompiler.cpp +++ b/solc/jsonCompiler.cpp @@ -21,6 +21,7 @@ */ #include <string> +#include <functional> #include <iostream> #include <json/json.h> #include <libdevcore/Common.h> @@ -47,10 +48,14 @@ extern "C" { typedef void (*CStyleReadFileCallback)(char const* _path, char** o_contents, char** o_error); } -string formatError(Exception const& _exception, string const& _name, CompilerStack const& _compiler) +string formatError( + Exception const& _exception, + string const& _name, + function<Scanner const&(string const&)> const& _scannerFromSourceName +) { ostringstream errorOutput; - SourceReferenceFormatter::printExceptionInformation(errorOutput, _exception, _name, _compiler); + SourceReferenceFormatter::printExceptionInformation(errorOutput, _exception, _name, _scannerFromSourceName); return errorOutput.str(); } @@ -150,6 +155,7 @@ string compile(StringMap const& _sources, bool _optimize, CStyleReadFileCallback }; } CompilerStack compiler(true, readCallback); + auto scannerFromSourceName = [&](string const& _sourceName) -> solidity::Scanner const& { return compiler.scanner(_sourceName); }; bool success = false; try { @@ -161,22 +167,22 @@ string compile(StringMap const& _sources, bool _optimize, CStyleReadFileCallback errors.append(formatError( *error, (err->type() == Error::Type::Warning) ? "Warning" : "Error", - compiler + scannerFromSourceName )); } success = succ; // keep success false on exception } catch (Error const& error) { - errors.append(formatError(error, error.typeName(), compiler)); + errors.append(formatError(error, error.typeName(), scannerFromSourceName)); } catch (CompilerError const& exception) { - errors.append(formatError(exception, "Compiler error", compiler)); + errors.append(formatError(exception, "Compiler error", scannerFromSourceName)); } catch (InternalCompilerError const& exception) { - errors.append(formatError(exception, "Internal compiler error", compiler)); + errors.append(formatError(exception, "Internal compiler error", scannerFromSourceName)); } catch (Exception const& exception) { |
