mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Refactor: Replace inheritance hierarchy by most derived contract.
This commit is contained in:
@@ -31,6 +31,12 @@ using namespace solidity;
|
||||
using namespace solidity::util;
|
||||
using namespace solidity::frontend;
|
||||
|
||||
ContractDefinition const& IRGenerationContext::mostDerivedContract() const
|
||||
{
|
||||
solAssert(m_mostDerivedContract, "Most derived contract requested but not set.");
|
||||
return *m_mostDerivedContract;
|
||||
}
|
||||
|
||||
IRVariable const& IRGenerationContext::addLocalVariable(VariableDeclaration const& _varDecl)
|
||||
{
|
||||
auto const& [it, didInsert] = m_localVariables.emplace(
|
||||
@@ -70,26 +76,9 @@ string IRGenerationContext::functionName(VariableDeclaration const& _varDecl)
|
||||
return "getter_fun_" + _varDecl.name() + "_" + to_string(_varDecl.id());
|
||||
}
|
||||
|
||||
FunctionDefinition const& IRGenerationContext::virtualFunction(FunctionDefinition const& _function)
|
||||
{
|
||||
// @TODO previously, we had to distinguish creation context and runtime context,
|
||||
// but since we do not work with jump positions anymore, this should not be a problem, right?
|
||||
string name = _function.name();
|
||||
FunctionType functionType(_function);
|
||||
for (auto const& contract: m_inheritanceHierarchy)
|
||||
for (FunctionDefinition const* function: contract->definedFunctions())
|
||||
if (
|
||||
function->name() == name &&
|
||||
!function->isConstructor() &&
|
||||
FunctionType(*function).asCallableFunction(false)->hasEqualParameterTypes(functionType)
|
||||
)
|
||||
return *function;
|
||||
solAssert(false, "Super function " + name + " not found.");
|
||||
}
|
||||
|
||||
string IRGenerationContext::virtualFunctionName(FunctionDefinition const& _functionDeclaration)
|
||||
{
|
||||
return functionName(virtualFunction(_functionDeclaration));
|
||||
return functionName(_functionDeclaration.resolveVirtual(mostDerivedContract()));
|
||||
}
|
||||
|
||||
string IRGenerationContext::newYulVariable()
|
||||
@@ -120,7 +109,7 @@ string IRGenerationContext::internalDispatch(size_t _in, size_t _out)
|
||||
templ("arrow", _out > 0 ? "->" : "");
|
||||
templ("out", suffixedVariableNameList("out_", 0, _out));
|
||||
vector<map<string, string>> functions;
|
||||
for (auto const& contract: m_inheritanceHierarchy)
|
||||
for (auto const& contract: mostDerivedContract().annotation().linearizedBaseContracts)
|
||||
for (FunctionDefinition const* function: contract->definedFunctions())
|
||||
if (
|
||||
!function->isConstructor() &&
|
||||
|
||||
@@ -61,11 +61,12 @@ public:
|
||||
|
||||
MultiUseYulFunctionCollector& functionCollector() { return m_functions; }
|
||||
|
||||
/// Sets the current inheritance hierarchy from derived to base.
|
||||
void setInheritanceHierarchy(std::vector<ContractDefinition const*> _hierarchy)
|
||||
/// Sets the most derived contract (the one currently being compiled)>
|
||||
void setMostDerivedContract(ContractDefinition const& _mostDerivedContract)
|
||||
{
|
||||
m_inheritanceHierarchy = std::move(_hierarchy);
|
||||
m_mostDerivedContract = &_mostDerivedContract;
|
||||
}
|
||||
ContractDefinition const& mostDerivedContract() const;
|
||||
|
||||
|
||||
IRVariable const& addLocalVariable(VariableDeclaration const& _varDecl);
|
||||
@@ -81,7 +82,6 @@ public:
|
||||
|
||||
std::string functionName(FunctionDefinition const& _function);
|
||||
std::string functionName(VariableDeclaration const& _varDecl);
|
||||
FunctionDefinition const& virtualFunction(FunctionDefinition const& _functionDeclaration);
|
||||
std::string virtualFunctionName(FunctionDefinition const& _functionDeclaration);
|
||||
|
||||
std::string newYulVariable();
|
||||
@@ -103,7 +103,7 @@ private:
|
||||
langutil::EVMVersion m_evmVersion;
|
||||
RevertStrings m_revertStrings;
|
||||
OptimiserSettings m_optimiserSettings;
|
||||
std::vector<ContractDefinition const*> m_inheritanceHierarchy;
|
||||
ContractDefinition const* m_mostDerivedContract = nullptr;
|
||||
std::map<VariableDeclaration const*, IRVariable> m_localVariables;
|
||||
/// Storage offsets of state variables
|
||||
std::map<VariableDeclaration const*, std::pair<u256, unsigned>> m_stateVariables;
|
||||
|
||||
@@ -110,7 +110,7 @@ string IRGenerator::generate(ContractDefinition const& _contract)
|
||||
t("functions", m_context.functionCollector().requestedFunctions());
|
||||
|
||||
resetContext(_contract);
|
||||
m_context.setInheritanceHierarchy(_contract.annotation().linearizedBaseContracts);
|
||||
m_context.setMostDerivedContract(_contract);
|
||||
t("RuntimeObject", runtimeObjectName(_contract));
|
||||
t("dispatch", dispatchRoutine(_contract));
|
||||
for (auto const* contract: _contract.annotation().linearizedBaseContracts)
|
||||
@@ -389,7 +389,7 @@ void IRGenerator::resetContext(ContractDefinition const& _contract)
|
||||
);
|
||||
m_context = IRGenerationContext(m_evmVersion, m_context.revertStrings(), m_optimiserSettings);
|
||||
|
||||
m_context.setInheritanceHierarchy(_contract.annotation().linearizedBaseContracts);
|
||||
m_context.setMostDerivedContract(_contract);
|
||||
for (auto const& var: ContractType(_contract).stateVariables())
|
||||
m_context.addStateVariable(*get<0>(var), get<1>(var), get<2>(var));
|
||||
}
|
||||
|
||||
@@ -1165,7 +1165,7 @@ void IRGeneratorForStatements::endVisit(Identifier const& _identifier)
|
||||
return;
|
||||
}
|
||||
else if (FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition const*>(declaration))
|
||||
define(_identifier) << to_string(m_context.virtualFunction(*functionDef).id()) << "\n";
|
||||
define(_identifier) << to_string(functionDef->resolveVirtual(m_context.mostDerivedContract()).id()) << "\n";
|
||||
else if (VariableDeclaration const* varDecl = dynamic_cast<VariableDeclaration const*>(declaration))
|
||||
{
|
||||
// TODO for the constant case, we have to be careful:
|
||||
|
||||
Reference in New Issue
Block a user