diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 55640b482..e605c6b48 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -1060,25 +1060,17 @@ void CompilerStack::generateEWasm(ContractDefinition const& _contract) return; // Re-parse the Yul IR in EVM dialect - yul::AssemblyStack evmStack(m_evmVersion, yul::AssemblyStack::Language::StrictAssembly, m_optimiserSettings); - evmStack.parseAndAnalyze("", compiledContract.yulIROptimized); + yul::AssemblyStack stack(m_evmVersion, yul::AssemblyStack::Language::StrictAssembly, m_optimiserSettings); + stack.parseAndAnalyze("", compiledContract.yulIROptimized); - // Turn into eWasm dialect - yul::Object ewasmObject = yul::EVMToEWasmTranslator( - yul::EVMDialect::strictAssemblyForEVMObjects(m_evmVersion) - ).run(*evmStack.parserResult()); + stack.optimize(); + stack.translate(yul::AssemblyStack::Language::EWasm); + stack.optimize(); - // Re-inject into an assembly stack for the eWasm dialect - yul::AssemblyStack ewasmStack(m_evmVersion, yul::AssemblyStack::Language::EWasm, m_optimiserSettings); - // TODO this is a hack for now - provide as structured AST! - ewasmStack.parseAndAnalyze("", "{}"); - *ewasmStack.parserResult() = move(ewasmObject); - ewasmStack.optimize(); - - //cout << yul::AsmPrinter{}(*ewasmStack.parserResult()->code) << endl; + //cout << yul::AsmPrinter{}(*stack.parserResult()->code) << endl; // Turn into eWasm text representation. - auto result = ewasmStack.assemble(yul::AssemblyStack::Machine::eWasm); + auto result = stack.assemble(yul::AssemblyStack::Machine::eWasm); compiledContract.eWasm = std::move(result.assembly); compiledContract.eWasmObject = std::move(*result.bytecode); } diff --git a/libyul/AssemblyStack.cpp b/libyul/AssemblyStack.cpp index 87df95f37..7851101af 100644 --- a/libyul/AssemblyStack.cpp +++ b/libyul/AssemblyStack.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -102,6 +103,23 @@ void AssemblyStack::optimize() solAssert(analyzeParsed(), "Invalid source code after optimization."); } +void AssemblyStack::translate(AssemblyStack::Language _targetLanguage) +{ + if (m_language == _targetLanguage) + return; + + solAssert( + m_language == Language::StrictAssembly && _targetLanguage == Language::EWasm, + "Invalid language combination" + ); + + *m_parserResult = EVMToEWasmTranslator( + languageToDialect(m_language, m_evmVersion) + ).run(*parserResult()); + + m_language = _targetLanguage; +} + bool AssemblyStack::analyzeParsed() { solAssert(m_parserResult, ""); diff --git a/libyul/AssemblyStack.h b/libyul/AssemblyStack.h index 8367ce786..a6dcd0b37 100644 --- a/libyul/AssemblyStack.h +++ b/libyul/AssemblyStack.h @@ -81,6 +81,9 @@ public: /// If the settings (see constructor) disabled the optimizer, nothing is done here. void optimize(); + /// Translate the source to a different language / dialect. + void translate(Language _targetLanguage); + /// Run the assembly step (should only be called after parseAndAnalyze). MachineAssemblyObject assemble(Machine _machine) const; diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 6f22e08e2..48f04d564 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -1364,14 +1364,14 @@ bool CommandLineInterface::assemble( for (auto const& sourceAndStack: assemblyStacks) { auto const& stack = sourceAndStack.second; - unique_ptr formatter; - if (m_args.count(g_argNewReporter)) - formatter = make_unique(serr(false), m_coloredOutput); - else - formatter = make_unique(serr(false)); - for (auto const& error: stack.errors()) { + unique_ptr formatter; + if (m_args.count(g_argNewReporter)) + formatter = make_unique(serr(false), m_coloredOutput); + else + formatter = make_unique(serr(false)); + g_hasOutput = true; formatter->printErrorInformation(*error); } @@ -1384,19 +1384,27 @@ bool CommandLineInterface::assemble( for (auto const& src: m_sourceCodes) { - // TODO translate from EVM to eWasm if - // _language is EVM and _targetMachine is EWasm - string machine = _targetMachine == yul::AssemblyStack::Machine::EVM ? "EVM" : _targetMachine == yul::AssemblyStack::Machine::EVM15 ? "EVM 1.5" : "eWasm"; sout() << endl << "======= " << src.first << " (" << machine << ") =======" << endl; + yul::AssemblyStack& stack = assemblyStacks[src.first]; sout() << endl << "Pretty printed source:" << endl; sout() << stack.print() << endl; + if (_language != yul::AssemblyStack::Language::EWasm && _targetMachine == yul::AssemblyStack::Machine::eWasm) + { + stack.translate(yul::AssemblyStack::Language::EWasm); + stack.optimize(); + + sout() << endl << "==========================" << endl; + sout() << endl << "Translated source:" << endl; + sout() << stack.print() << endl; + } + yul::MachineAssemblyObject object; try {