[libsolidity] Basic output generation of assembly json import.

This commit is contained in:
Alexander Arlt 2021-11-08 20:02:05 -05:00
parent f11044d9dd
commit 4473b3ca2d
2 changed files with 61 additions and 46 deletions

View File

@ -394,7 +394,7 @@ void CompilerStack::importEvmAssemblyJson(map<string, Json::Value> const& _sourc
if (m_stackState != Empty) if (m_stackState != Empty)
solThrow(CompilerError, "Must call importEvmAssemblyJson only before the SourcesSet state."); solThrow(CompilerError, "Must call importEvmAssemblyJson only before the SourcesSet state.");
m_evmAssemblyJson = std::make_unique<Json::Value>(_sources.begin()->second); m_evmAssemblyJson[_sources.begin()->first] = _sources.begin()->second;
m_importedSources = true; m_importedSources = true;
m_stackState = SourcesSet; m_stackState = SourcesSet;
} }
@ -654,58 +654,73 @@ bool CompilerStack::compile(State _stopAfter)
if (m_hasError) if (m_hasError)
solThrow(CompilerError, "Called compile with errors."); solThrow(CompilerError, "Called compile with errors.");
// Only compile contracts individually which have been requested. if (!m_evmAssemblyJson.empty())
map<ContractDefinition const*, shared_ptr<Compiler const>> otherCompilers; {
solAssert(m_importedSources, "");
solAssert(m_evmAssemblyJson.size() == 1, "");
for (Source const* source: m_sourceOrder) string const evmAssemblyJsonSource = m_evmAssemblyJson.begin()->first;
for (ASTPointer<ASTNode> const& node: source->ast->nodes())
if (auto contract = dynamic_cast<ContractDefinition const*>(node.get())) m_contracts[evmAssemblyJsonSource].evmAssembly = make_shared<evmasm::Assembly>(evmAssemblyJsonSource);
if (isRequestedContract(*contract)) m_contracts[evmAssemblyJsonSource].evmAssembly->loadFromAssemblyJSON(m_evmAssemblyJson[evmAssemblyJsonSource]);
{ m_contracts[evmAssemblyJsonSource].object = m_contracts[evmAssemblyJsonSource].evmAssembly->assemble();
try
m_contracts[evmAssemblyJsonSource].evmRuntimeAssembly = make_shared<evmasm::Assembly>(evmAssemblyJsonSource);
m_contracts[evmAssemblyJsonSource].evmRuntimeAssembly->loadFromAssemblyJSON(m_evmAssemblyJson[evmAssemblyJsonSource][".data"]["0"]);
m_contracts[evmAssemblyJsonSource].runtimeObject = m_contracts[evmAssemblyJsonSource].evmRuntimeAssembly->assemble();
}
else
{
// Only compile contracts individually which have been requested.
map<ContractDefinition const*, shared_ptr<Compiler const>> otherCompilers;
for (Source const* source: m_sourceOrder)
for (ASTPointer<ASTNode> const& node: source->ast->nodes())
if (auto contract = dynamic_cast<ContractDefinition const*>(node.get()))
if (isRequestedContract(*contract))
{ {
if (m_viaIR || m_generateIR || m_generateEwasm) try
generateIR(*contract);
if (m_generateEvmBytecode)
{ {
if (m_viaIR) if (m_viaIR || m_generateIR || m_generateEwasm)
generateEVMFromIR(*contract); generateIR(*contract);
else if (m_generateEvmBytecode)
compileContract(*contract, otherCompilers); {
if (m_viaIR)
generateEVMFromIR(*contract);
else
compileContract(*contract, otherCompilers);
}
if (m_generateEwasm)
generateEwasm(*contract);
} }
if (m_generateEwasm) catch (Error const& _error)
generateEwasm(*contract);
}
catch (Error const& _error)
{
if (_error.type() != Error::Type::CodeGenerationError)
throw;
m_errorReporter.error(_error.errorId(), _error.type(), SourceLocation(), _error.what());
return false;
}
catch (UnimplementedFeatureError const& _unimplementedError)
{
if (
SourceLocation const* sourceLocation =
boost::get_error_info<langutil::errinfo_sourceLocation>(_unimplementedError)
)
{ {
string const* comment = _unimplementedError.comment(); if (_error.type() != Error::Type::CodeGenerationError)
m_errorReporter.error( throw;
1834_error, m_errorReporter.error(_error.errorId(), _error.type(), SourceLocation(), _error.what());
Error::Type::CodeGenerationError,
*sourceLocation,
"Unimplemented feature error" +
((comment && !comment->empty()) ? ": " + *comment : string{}) +
" in " +
_unimplementedError.lineInfo()
);
return false; return false;
} }
else catch (UnimplementedFeatureError const& _unimplementedError)
throw; {
if (SourceLocation const* sourceLocation
= boost::get_error_info<langutil::errinfo_sourceLocation>(_unimplementedError))
{
string const* comment = _unimplementedError.comment();
m_errorReporter.error(
1834_error,
Error::Type::CodeGenerationError,
*sourceLocation,
"Unimplemented feature error"
+ ((comment && !comment->empty()) ? ": " + *comment : string{}) + " in "
+ _unimplementedError.lineInfo());
return false;
}
else
throw;
}
} }
} }
m_stackState = CompilationSuccessful; m_stackState = CompilationSuccessful;
this->link(); this->link();
return true; return true;

View File

@ -501,7 +501,7 @@ private:
std::map<std::string const, Source> m_sources; std::map<std::string const, Source> m_sources;
// if imported, store AST-JSONS for each filename // if imported, store AST-JSONS for each filename
std::map<std::string, Json::Value> m_sourceJsons; std::map<std::string, Json::Value> m_sourceJsons;
std::unique_ptr<Json::Value> m_evmAssemblyJson; std::map<std::string, Json::Value> m_evmAssemblyJson;
std::vector<std::string> m_unhandledSMTLib2Queries; std::vector<std::string> m_unhandledSMTLib2Queries;
std::map<util::h256, std::string> m_smtlib2Responses; std::map<util::h256, std::string> m_smtlib2Responses;
std::shared_ptr<GlobalContext> m_globalContext; std::shared_ptr<GlobalContext> m_globalContext;