From 706e6aaefa1d0813a8e9bcfe9aee7a673923312c Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Mon, 9 May 2022 23:03:43 +0200 Subject: [PATCH] Assembly::loadFromAssemblyJSON(..) as static factory function. --- libevmasm/Assembly.cpp | 30 ++++++++++++------------- libevmasm/Assembly.h | 2 +- libsolidity/interface/CompilerStack.cpp | 10 ++++----- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index e1b9d62ac..10fd20687 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -409,24 +409,25 @@ Json::Value Assembly::assemblyJSON(map const& _sourceIndices, return root; } -bool Assembly::loadFromAssemblyJSON(Json::Value const& _json, bool _loadSources /* = true */) +std::shared_ptr Assembly::loadFromAssemblyJSON(Json::Value const& _json, std::vector const& _sourceList /* = {} */, bool _isCreation /* = true */) { if (!_json[".code"].isArray()) - return false; - bool success{true}; + return {}; - if (_loadSources) + std::shared_ptr result = std::make_shared(_isCreation, ""); + vector sourceList; + if (_sourceList.empty()) { - vector sourceList; if (_json.isMember("sourceList")) for (auto const& it: _json["sourceList"]) sourceList.emplace_back(it.asString()); - setSources(sourceList); } - - addAssemblyItemsFromJSON(_json[".code"]); + else + sourceList = _sourceList; + result->setSources(sourceList); + result->addAssemblyItemsFromJSON(_json[".code"]); if (_json[".auxdata"].isString()) - m_auxiliaryData = fromHex(_json[".auxdata"].asString()); + result->m_auxiliaryData = fromHex(_json[".auxdata"].asString()); Json::Value const& data = _json[".data"]; 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(); Json::Value const& code = data[key]; if (code.isString()) - m_data[h256(fromHex(key))] = fromHex(code.asString()); + result->m_data[h256(fromHex(key))] = fromHex(code.asString()); else { - shared_ptr subassembly = make_shared(false, ""); - subassembly->setSources(sources()); - success &= subassembly->loadFromAssemblyJSON(code, false); - m_subs.emplace_back(subassembly); + std::shared_ptr subassembly(Assembly::loadFromAssemblyJSON(code, sourceList, /* isCreation = */ false)); + assertThrow(subassembly, AssemblyException, ""); + result->m_subs.emplace_back(std::make_shared(*subassembly)); } } - return success; + return result; } AssemblyItem Assembly::namedTag(string const& _name, size_t _params, size_t _returns, optional _sourceID) diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index 9ae86b110..7d0973387 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -156,7 +156,7 @@ public: /// @param _json JSON object containing assembly /// @param _loadSources true, if source list should be included, false otherwise. /// @returns true on success, false otherwise - bool loadFromAssemblyJSON(Json::Value const& _json, bool _loadSources = true); + static std::shared_ptr loadFromAssemblyJSON(Json::Value const& _json, std::vector const& _sourceList = {}, bool _isCreation = true); /// Mark this assembly as invalid. Calling ``assemble`` on it will throw. void markAsInvalid() { m_invalid = true; } diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 6787e2ddd..f8aacde70 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -423,7 +423,7 @@ void CompilerStack::importEvmAssemblyJson(std::map con if (m_stackState != Empty) 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")) for (auto const& item: jsonValue["sourceList"]) { @@ -696,15 +696,13 @@ bool CompilerStack::compile(State _stopAfter) optimiserSettings.runJumpdestRemover = m_optimiserSettings.runJumpdestRemover; optimiserSettings.runPeephole = m_optimiserSettings.runPeephole; - m_contracts[evmSourceName].evmAssembly = make_shared(true, evmSourceName); - m_contracts[evmSourceName].evmAssembly->loadFromAssemblyJSON(m_evmAssemblyJson[evmSourceName]); + m_contracts[evmSourceName].evmAssembly = evmasm::Assembly::loadFromAssemblyJSON(m_evmAssemblyJson[evmSourceName]); if (m_optimiserSettings.enabled) m_contracts[evmSourceName].evmAssembly->optimise(optimiserSettings); m_contracts[evmSourceName].object = m_contracts[evmSourceName].evmAssembly->assemble(); - m_contracts[evmSourceName].evmRuntimeAssembly = make_shared(false, evmSourceName); - m_contracts[evmSourceName].evmRuntimeAssembly->setSources(m_contracts[evmSourceName].evmAssembly->sources()); - m_contracts[evmSourceName].evmRuntimeAssembly->loadFromAssemblyJSON(m_evmAssemblyJson[evmSourceName][".data"]["0"], false); + m_contracts[evmSourceName].evmRuntimeAssembly = std::make_shared(m_contracts[evmSourceName].evmAssembly->sub(0)); + solAssert(m_contracts[evmSourceName].evmRuntimeAssembly->isCreation() == false, ""); if (m_optimiserSettings.enabled) m_contracts[evmSourceName].evmRuntimeAssembly->optimise(optimiserSettings); m_contracts[evmSourceName].runtimeObject = m_contracts[evmSourceName].evmRuntimeAssembly->assemble();