mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[evmasm::EVMAssemblyStack] Implement AbstractAssemblyStack.
This commit is contained in:
parent
e087ef6d06
commit
52f2d4b6e0
@ -22,8 +22,6 @@
|
|||||||
#include <liblangutil/Exceptions.h>
|
#include <liblangutil/Exceptions.h>
|
||||||
#include <libsolidity/codegen/CompilerContext.h>
|
#include <libsolidity/codegen/CompilerContext.h>
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
using namespace solidity::langutil;
|
using namespace solidity::langutil;
|
||||||
using namespace solidity::frontend;
|
using namespace solidity::frontend;
|
||||||
@ -40,7 +38,10 @@ bool EVMAssemblyStack::parseAndAnalyze(string const& _sourceName, string const&
|
|||||||
if (!jsonParseStrict(_source, m_json))
|
if (!jsonParseStrict(_source, m_json))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_evmAssembly = evmasm::Assembly::fromJSON(m_json);
|
auto result = evmasm::Assembly::fromJSON(m_json);
|
||||||
|
m_evmAssembly = result.first;
|
||||||
|
m_sourceList = result.second;
|
||||||
|
|
||||||
return m_evmAssembly != nullptr;
|
return m_evmAssembly != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,12 +52,81 @@ void EVMAssemblyStack::assemble()
|
|||||||
solAssert(!m_evmRuntimeAssembly);
|
solAssert(!m_evmRuntimeAssembly);
|
||||||
|
|
||||||
m_object = m_evmAssembly->assemble();
|
m_object = m_evmAssembly->assemble();
|
||||||
|
m_sourceMapping.emplace(AssemblyItem::computeSourceMapping(m_evmAssembly->items(), sourceIndices()));
|
||||||
if (m_evmAssembly->numSubs() > 0)
|
if (m_evmAssembly->numSubs() > 0)
|
||||||
{
|
{
|
||||||
m_evmRuntimeAssembly = make_shared<evmasm::Assembly>(m_evmAssembly->sub(0));
|
m_evmRuntimeAssembly = make_shared<evmasm::Assembly>(m_evmAssembly->sub(0));
|
||||||
solAssert(m_evmRuntimeAssembly && !m_evmRuntimeAssembly->isCreation());
|
solAssert(m_evmRuntimeAssembly && !m_evmRuntimeAssembly->isCreation());
|
||||||
|
m_runtimeSourceMapping.emplace(AssemblyItem::computeSourceMapping(m_evmRuntimeAssembly->items(), sourceIndices()));
|
||||||
m_runtimeObject = m_evmRuntimeAssembly->assemble();
|
m_runtimeObject = m_evmRuntimeAssembly->assemble();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LinkerObject const& EVMAssemblyStack::object(string const& _contractName) const
|
||||||
|
{
|
||||||
|
solAssert(_contractName == m_name);
|
||||||
|
return m_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkerObject const& EVMAssemblyStack::runtimeObject(string const& _contractName) const
|
||||||
|
{
|
||||||
|
solAssert(_contractName == m_name);
|
||||||
|
return m_runtimeObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
map<string, unsigned> EVMAssemblyStack::sourceIndices() const
|
||||||
|
{
|
||||||
|
solAssert(m_evmAssembly);
|
||||||
|
map<string, unsigned> indices;
|
||||||
|
unsigned index = 0;
|
||||||
|
for (auto const& s: m_sourceList)
|
||||||
|
if (s != CompilerContext::yulUtilityFileName())
|
||||||
|
indices[s] = index++;
|
||||||
|
|
||||||
|
if (indices.find(CompilerContext::yulUtilityFileName()) == indices.end())
|
||||||
|
indices[CompilerContext::yulUtilityFileName()] = index++;
|
||||||
|
return indices;
|
||||||
|
}
|
||||||
|
|
||||||
|
string const* EVMAssemblyStack::sourceMapping(string const& _contractName) const
|
||||||
|
{
|
||||||
|
solAssert(_contractName == m_name);
|
||||||
|
return m_sourceMapping.has_value() ? &m_sourceMapping.value() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
string const* EVMAssemblyStack::runtimeSourceMapping(string const& _contractName) const
|
||||||
|
{
|
||||||
|
solAssert(_contractName == m_name);
|
||||||
|
return m_runtimeSourceMapping.has_value() ? &m_runtimeSourceMapping.value() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value EVMAssemblyStack::assemblyJSON(string const& _contractName) const
|
||||||
|
{
|
||||||
|
solAssert(_contractName == m_name);
|
||||||
|
solAssert(m_evmAssembly);
|
||||||
|
vector<string> sources = sourceNames();
|
||||||
|
if (find(sources.begin(), sources.end(), CompilerContext::yulUtilityFileName()) == sources.end())
|
||||||
|
sources.emplace_back(CompilerContext::yulUtilityFileName());
|
||||||
|
return m_evmAssembly->assemblyJSON(sources);
|
||||||
|
}
|
||||||
|
|
||||||
|
string EVMAssemblyStack::assemblyString(string const& _contractName, StringMap const& _sourceCodes) const
|
||||||
|
{
|
||||||
|
solAssert(_contractName == m_name);
|
||||||
|
solAssert(m_evmAssembly);
|
||||||
|
return m_evmAssembly->assemblyString(m_debugInfoSelection, _sourceCodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
string const EVMAssemblyStack::filesystemFriendlyName(string const& _contractName) const
|
||||||
|
{
|
||||||
|
solAssert(_contractName == m_name);
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<string> EVMAssemblyStack::sourceNames() const
|
||||||
|
{
|
||||||
|
return m_sourceList;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace solidity::evmasm
|
} // namespace solidity::evmasm
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <libevmasm/AbstractAssemblyStack.h>
|
||||||
#include <libevmasm/Assembly.h>
|
#include <libevmasm/Assembly.h>
|
||||||
#include <libevmasm/LinkerObject.h>
|
#include <libevmasm/LinkerObject.h>
|
||||||
|
|
||||||
@ -29,25 +30,41 @@
|
|||||||
namespace solidity::evmasm
|
namespace solidity::evmasm
|
||||||
{
|
{
|
||||||
|
|
||||||
class EVMAssemblyStack
|
class EVMAssemblyStack: public AbstractAssemblyStack
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit EVMAssemblyStack(langutil::EVMVersion _evmVersion): m_evmVersion(_evmVersion) {}
|
explicit EVMAssemblyStack(langutil::EVMVersion _evmVersion): m_evmVersion(_evmVersion) {}
|
||||||
|
|
||||||
/// Runs parsing and analysis, returns false if input cannot be assembled.
|
|
||||||
/// Multiple calls overwrite the previous state.
|
|
||||||
bool parseAndAnalyze(std::string const& _sourceName, std::string const& _source);
|
bool parseAndAnalyze(std::string const& _sourceName, std::string const& _source);
|
||||||
|
|
||||||
void assemble();
|
void assemble();
|
||||||
|
|
||||||
std::string const& name() const { return m_name; }
|
std::string const& name() const { return m_name; }
|
||||||
|
|
||||||
evmasm::LinkerObject const& object() const { return m_object; }
|
virtual LinkerObject const& object(std::string const& _contractName) const override;
|
||||||
evmasm::LinkerObject const& runtimeObject() const { return m_runtimeObject; }
|
virtual LinkerObject const& runtimeObject(std::string const& _contractName) const override;
|
||||||
|
|
||||||
std::shared_ptr<evmasm::Assembly> const& evmAssembly() const { return m_evmAssembly; }
|
std::shared_ptr<evmasm::Assembly> const& evmAssembly() const { return m_evmAssembly; }
|
||||||
std::shared_ptr<evmasm::Assembly> const& evmRuntimeAssembly() const { return m_evmRuntimeAssembly; }
|
std::shared_ptr<evmasm::Assembly> const& evmRuntimeAssembly() const { return m_evmRuntimeAssembly; }
|
||||||
|
|
||||||
|
virtual std::string const* sourceMapping(std::string const& _contractName) const override;
|
||||||
|
virtual std::string const* runtimeSourceMapping(std::string const& _contractName) const override;
|
||||||
|
|
||||||
|
virtual Json::Value assemblyJSON(std::string const& _contractName) const override;
|
||||||
|
virtual std::string assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const override;
|
||||||
|
|
||||||
|
virtual std::string const filesystemFriendlyName(std::string const& _contractName) const override;
|
||||||
|
|
||||||
|
virtual std::vector<std::string> contractNames() const override { return {m_name}; }
|
||||||
|
virtual std::vector<std::string> sourceNames() const override;
|
||||||
|
std::map<std::string, unsigned> sourceIndices() const;
|
||||||
|
|
||||||
|
virtual bool compilationSuccessful() const override { return m_evmAssembly != nullptr; }
|
||||||
|
|
||||||
|
void selectDebugInfo(langutil::DebugInfoSelection _debugInfoSelection)
|
||||||
|
{
|
||||||
|
m_debugInfoSelection = _debugInfoSelection;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
langutil::EVMVersion m_evmVersion;
|
langutil::EVMVersion m_evmVersion;
|
||||||
@ -57,6 +74,10 @@ private:
|
|||||||
std::shared_ptr<evmasm::Assembly> m_evmRuntimeAssembly;
|
std::shared_ptr<evmasm::Assembly> m_evmRuntimeAssembly;
|
||||||
evmasm::LinkerObject m_object; ///< Deployment object (includes the runtime sub-object).
|
evmasm::LinkerObject m_object; ///< Deployment object (includes the runtime sub-object).
|
||||||
evmasm::LinkerObject m_runtimeObject; ///< Runtime object.
|
evmasm::LinkerObject m_runtimeObject; ///< Runtime object.
|
||||||
|
std::vector<std::string> m_sourceList;
|
||||||
|
langutil::DebugInfoSelection m_debugInfoSelection = langutil::DebugInfoSelection::Default();
|
||||||
|
std::optional<std::string const> m_sourceMapping;
|
||||||
|
std::optional<std::string const> m_runtimeSourceMapping;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace solidity::evmasm
|
} // namespace solidity::evmasm
|
||||||
|
Loading…
Reference in New Issue
Block a user