Assembly::loadFromAssemblyJSON(..) as static factory function.

This commit is contained in:
Alexander Arlt 2022-05-09 23:03:43 +02:00
parent 8e55cacd7c
commit 706e6aaefa
3 changed files with 20 additions and 22 deletions

View File

@ -409,24 +409,25 @@ Json::Value Assembly::assemblyJSON(map<string, unsigned> const& _sourceIndices,
return root; return root;
} }
bool Assembly::loadFromAssemblyJSON(Json::Value const& _json, bool _loadSources /* = true */) std::shared_ptr<Assembly> Assembly::loadFromAssemblyJSON(Json::Value const& _json, std::vector<std::string> const& _sourceList /* = {} */, bool _isCreation /* = true */)
{ {
if (!_json[".code"].isArray()) if (!_json[".code"].isArray())
return false; return {};
bool success{true};
if (_loadSources) std::shared_ptr<Assembly> result = std::make_shared<Assembly>(_isCreation, "");
vector<string> sourceList;
if (_sourceList.empty())
{ {
vector<string> sourceList;
if (_json.isMember("sourceList")) if (_json.isMember("sourceList"))
for (auto const& it: _json["sourceList"]) for (auto const& it: _json["sourceList"])
sourceList.emplace_back(it.asString()); sourceList.emplace_back(it.asString());
setSources(sourceList);
} }
else
addAssemblyItemsFromJSON(_json[".code"]); sourceList = _sourceList;
result->setSources(sourceList);
result->addAssemblyItemsFromJSON(_json[".code"]);
if (_json[".auxdata"].isString()) if (_json[".auxdata"].isString())
m_auxiliaryData = fromHex(_json[".auxdata"].asString()); result->m_auxiliaryData = fromHex(_json[".auxdata"].asString());
Json::Value const& data = _json[".data"]; Json::Value const& data = _json[".data"];
for (Json::ValueConstIterator itr = data.begin(); itr != data.end(); itr++) for (Json::ValueConstIterator itr = data.begin(); itr != data.end(); itr++)
{ {
@ -434,16 +435,15 @@ bool Assembly::loadFromAssemblyJSON(Json::Value const& _json, bool _loadSources
std::string key = itr.key().asString(); std::string key = itr.key().asString();
Json::Value const& code = data[key]; Json::Value const& code = data[key];
if (code.isString()) if (code.isString())
m_data[h256(fromHex(key))] = fromHex(code.asString()); result->m_data[h256(fromHex(key))] = fromHex(code.asString());
else else
{ {
shared_ptr<Assembly> subassembly = make_shared<Assembly>(false, ""); std::shared_ptr<Assembly> subassembly(Assembly::loadFromAssemblyJSON(code, sourceList, /* isCreation = */ false));
subassembly->setSources(sources()); assertThrow(subassembly, AssemblyException, "");
success &= subassembly->loadFromAssemblyJSON(code, false); result->m_subs.emplace_back(std::make_shared<Assembly>(*subassembly));
m_subs.emplace_back(subassembly);
} }
} }
return success; return result;
} }
AssemblyItem Assembly::namedTag(string const& _name, size_t _params, size_t _returns, optional<uint64_t> _sourceID) AssemblyItem Assembly::namedTag(string const& _name, size_t _params, size_t _returns, optional<uint64_t> _sourceID)

View File

@ -156,7 +156,7 @@ public:
/// @param _json JSON object containing assembly /// @param _json JSON object containing assembly
/// @param _loadSources true, if source list should be included, false otherwise. /// @param _loadSources true, if source list should be included, false otherwise.
/// @returns true on success, false otherwise /// @returns true on success, false otherwise
bool loadFromAssemblyJSON(Json::Value const& _json, bool _loadSources = true); static std::shared_ptr<Assembly> loadFromAssemblyJSON(Json::Value const& _json, std::vector<std::string> const& _sourceList = {}, bool _isCreation = true);
/// Mark this assembly as invalid. Calling ``assemble`` on it will throw. /// Mark this assembly as invalid. Calling ``assemble`` on it will throw.
void markAsInvalid() { m_invalid = true; } void markAsInvalid() { m_invalid = true; }

View File

@ -423,7 +423,7 @@ void CompilerStack::importEvmAssemblyJson(std::map<std::string, Json::Value> con
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.");
Json::Value jsonValue = _sources.begin()->second; Json::Value const& jsonValue = _sources.begin()->second;
if (jsonValue.isMember("sourceList")) if (jsonValue.isMember("sourceList"))
for (auto const& item: jsonValue["sourceList"]) for (auto const& item: jsonValue["sourceList"])
{ {
@ -696,15 +696,13 @@ bool CompilerStack::compile(State _stopAfter)
optimiserSettings.runJumpdestRemover = m_optimiserSettings.runJumpdestRemover; optimiserSettings.runJumpdestRemover = m_optimiserSettings.runJumpdestRemover;
optimiserSettings.runPeephole = m_optimiserSettings.runPeephole; optimiserSettings.runPeephole = m_optimiserSettings.runPeephole;
m_contracts[evmSourceName].evmAssembly = make_shared<evmasm::Assembly>(true, evmSourceName); m_contracts[evmSourceName].evmAssembly = evmasm::Assembly::loadFromAssemblyJSON(m_evmAssemblyJson[evmSourceName]);
m_contracts[evmSourceName].evmAssembly->loadFromAssemblyJSON(m_evmAssemblyJson[evmSourceName]);
if (m_optimiserSettings.enabled) if (m_optimiserSettings.enabled)
m_contracts[evmSourceName].evmAssembly->optimise(optimiserSettings); m_contracts[evmSourceName].evmAssembly->optimise(optimiserSettings);
m_contracts[evmSourceName].object = m_contracts[evmSourceName].evmAssembly->assemble(); m_contracts[evmSourceName].object = m_contracts[evmSourceName].evmAssembly->assemble();
m_contracts[evmSourceName].evmRuntimeAssembly = make_shared<evmasm::Assembly>(false, evmSourceName); m_contracts[evmSourceName].evmRuntimeAssembly = std::make_shared<evmasm::Assembly>(m_contracts[evmSourceName].evmAssembly->sub(0));
m_contracts[evmSourceName].evmRuntimeAssembly->setSources(m_contracts[evmSourceName].evmAssembly->sources()); solAssert(m_contracts[evmSourceName].evmRuntimeAssembly->isCreation() == false, "");
m_contracts[evmSourceName].evmRuntimeAssembly->loadFromAssemblyJSON(m_evmAssemblyJson[evmSourceName][".data"]["0"], false);
if (m_optimiserSettings.enabled) if (m_optimiserSettings.enabled)
m_contracts[evmSourceName].evmRuntimeAssembly->optimise(optimiserSettings); m_contracts[evmSourceName].evmRuntimeAssembly->optimise(optimiserSettings);
m_contracts[evmSourceName].runtimeObject = m_contracts[evmSourceName].evmRuntimeAssembly->assemble(); m_contracts[evmSourceName].runtimeObject = m_contracts[evmSourceName].evmRuntimeAssembly->assemble();