Merge pull request #7606 from ethereum/wasmBinaryAssemblyStack

Wasm binary assembly stack
This commit is contained in:
Alex Beregszaszi 2019-11-05 23:31:32 +00:00 committed by GitHub
commit eb0d72e825
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 33 additions and 6 deletions

View File

@ -7,6 +7,7 @@ Compiler Features:
* Code Generator: Use SELFBALANCE for ``address(this).balance`` if using Istanbul EVM * Code Generator: Use SELFBALANCE for ``address(this).balance`` if using Istanbul EVM
* SMTChecker: Add break/continue support to the CHC engine. * SMTChecker: Add break/continue support to the CHC engine.
* SMTChecker: Support assignments to multi-dimensional arrays and mappings. * SMTChecker: Support assignments to multi-dimensional arrays and mappings.
* EWasm: Experimental EWasm binary output.
Bugfixes: Bugfixes:

View File

@ -578,6 +578,14 @@ string const& CompilerStack::eWasm(string const& _contractName) const
return contract(_contractName).eWasm; return contract(_contractName).eWasm;
} }
eth::LinkerObject const& CompilerStack::eWasmObject(string const& _contractName) const
{
if (m_stackState != CompilationSuccessful)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Compilation was not successful."));
return contract(_contractName).eWasmObject;
}
eth::LinkerObject const& CompilerStack::object(string const& _contractName) const eth::LinkerObject const& CompilerStack::object(string const& _contractName) const
{ {
if (m_stackState != CompilationSuccessful) if (m_stackState != CompilationSuccessful)
@ -1047,7 +1055,9 @@ void CompilerStack::generateEWasm(ContractDefinition const& _contract)
//cout << yul::AsmPrinter{}(*ewasmStack.parserResult()->code) << endl; //cout << yul::AsmPrinter{}(*ewasmStack.parserResult()->code) << endl;
// Turn into eWasm text representation. // Turn into eWasm text representation.
compiledContract.eWasm = ewasmStack.assemble(yul::AssemblyStack::Machine::eWasm).assembly; auto result = ewasmStack.assemble(yul::AssemblyStack::Machine::eWasm);
compiledContract.eWasm = std::move(result.assembly);
compiledContract.eWasmObject = std::move(*result.bytecode);
} }
CompilerStack::Contract const& CompilerStack::contract(string const& _contractName) const CompilerStack::Contract const& CompilerStack::contract(string const& _contractName) const

View File

@ -232,9 +232,12 @@ public:
/// @returns the optimized IR representation of a contract. /// @returns the optimized IR representation of a contract.
std::string const& yulIROptimized(std::string const& _contractName) const; std::string const& yulIROptimized(std::string const& _contractName) const;
/// @returns the eWasm (text) representation of a contract. /// @returns the eWasm text representation of a contract.
std::string const& eWasm(std::string const& _contractName) const; std::string const& eWasm(std::string const& _contractName) const;
/// @returns the eWasm representation of a contract.
eth::LinkerObject const& eWasmObject(std::string const& _contractName) const;
/// @returns the assembled object for a contract. /// @returns the assembled object for a contract.
eth::LinkerObject const& object(std::string const& _contractName) const; eth::LinkerObject const& object(std::string const& _contractName) const;
@ -312,7 +315,8 @@ private:
eth::LinkerObject runtimeObject; ///< Runtime object. eth::LinkerObject runtimeObject; ///< Runtime object.
std::string yulIR; ///< Experimental Yul IR code. std::string yulIR; ///< Experimental Yul IR code.
std::string yulIROptimized; ///< Optimized experimental Yul IR code. std::string yulIROptimized; ///< Optimized experimental Yul IR code.
std::string eWasm; ///< Experimental eWasm code (text representation). std::string eWasm; ///< Experimental eWasm text representation
eth::LinkerObject eWasmObject; ///< Experimental eWasm code
mutable std::unique_ptr<std::string const> metadata; ///< The metadata json that will be hashed into the chain. mutable std::unique_ptr<std::string const> metadata; ///< The metadata json that will be hashed into the chain.
mutable std::unique_ptr<Json::Value const> abi; mutable std::unique_ptr<Json::Value const> abi;
mutable std::unique_ptr<Json::Value const> userDocumentation; mutable std::unique_ptr<Json::Value const> userDocumentation;
@ -346,7 +350,7 @@ private:
/// The IR is stored but otherwise unused. /// The IR is stored but otherwise unused.
void generateIR(ContractDefinition const& _contract); void generateIR(ContractDefinition const& _contract);
/// Generate eWasm text representation for a single contract. /// Generate eWasm representation for a single contract.
void generateEWasm(ContractDefinition const& _contract); void generateEWasm(ContractDefinition const& _contract);
/// Links all the known library addresses in the available objects. Any unknown /// Links all the known library addresses in the available objects. Any unknown

View File

@ -907,6 +907,8 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
// eWasm // eWasm
if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "ewasm.wast", wildcardMatchesExperimental)) if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "ewasm.wast", wildcardMatchesExperimental))
contractData["ewasm"]["wast"] = compilerStack.eWasm(contractName); contractData["ewasm"]["wast"] = compilerStack.eWasm(contractName);
if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "ewasm.wasm", wildcardMatchesExperimental))
contractData["ewasm"]["wasm"] = compilerStack.eWasmObject(contractName).toHex();
// EVM // EVM
Json::Value evmData(Json::objectValue); Json::Value evmData(Json::objectValue);

View File

@ -200,7 +200,10 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine) const
Dialect const& dialect = languageToDialect(m_language, EVMVersion{}); Dialect const& dialect = languageToDialect(m_language, EVMVersion{});
MachineAssemblyObject object; MachineAssemblyObject object;
object.assembly = EWasmObjectCompiler::compile(*m_parserResult, dialect).first; auto result = EWasmObjectCompiler::compile(*m_parserResult, dialect);
object.assembly = std::move(result.first);
object.bytecode = make_shared<dev::eth::LinkerObject>();
object.bytecode->bytecode = std::move(result.second);
return object; return object;
} }
} }

View File

@ -318,11 +318,18 @@ void CommandLineInterface::handleEWasm(string const& _contractName)
if (m_args.count(g_argEWasm)) if (m_args.count(g_argEWasm))
{ {
if (m_args.count(g_argOutputDir)) if (m_args.count(g_argOutputDir))
{
createFile(m_compiler->filesystemFriendlyName(_contractName) + ".wast", m_compiler->eWasm(_contractName)); createFile(m_compiler->filesystemFriendlyName(_contractName) + ".wast", m_compiler->eWasm(_contractName));
createFile(
m_compiler->filesystemFriendlyName(_contractName) + ".wasm",
asString(m_compiler->eWasmObject(_contractName).bytecode)
);
}
else else
{ {
sout() << "eWasm: " << endl; sout() << "EWasm text: " << endl;
sout() << m_compiler->eWasm(_contractName) << endl; sout() << m_compiler->eWasm(_contractName) << endl;
sout() << "EWasm binary (hex): " << m_compiler->eWasmObject(_contractName).toHex() << endl;
} }
} }
} }