mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Define a comparator for InternalDispatchMap to ensure deterministic ordering of dispatch functions
This commit is contained in:
parent
33ca90c284
commit
630fcc3a1d
@ -128,7 +128,7 @@ void IRGenerationContext::initializeInternalDispatch(InternalDispatchMap _intern
|
|||||||
{
|
{
|
||||||
solAssert(internalDispatchClean(), "");
|
solAssert(internalDispatchClean(), "");
|
||||||
|
|
||||||
for (set<FunctionDefinition const*> const& functions: _internalDispatch | boost::adaptors::map_values)
|
for (DispatchSet const& functions: _internalDispatch | boost::adaptors::map_values)
|
||||||
for (auto function: functions)
|
for (auto function: functions)
|
||||||
enqueueFunctionForCodeGeneration(*function);
|
enqueueFunctionForCodeGeneration(*function);
|
||||||
|
|
||||||
@ -147,7 +147,13 @@ void IRGenerationContext::addToInternalDispatch(FunctionDefinition const& _funct
|
|||||||
FunctionType const* functionType = TypeProvider::function(_function, FunctionType::Kind::Internal);
|
FunctionType const* functionType = TypeProvider::function(_function, FunctionType::Kind::Internal);
|
||||||
solAssert(functionType, "");
|
solAssert(functionType, "");
|
||||||
|
|
||||||
m_internalDispatchMap[YulArity::fromType(*functionType)].insert(&_function);
|
YulArity arity = YulArity::fromType(*functionType);
|
||||||
|
|
||||||
|
if (m_internalDispatchMap.count(arity) != 0 && m_internalDispatchMap[arity].count(&_function) != 0)
|
||||||
|
// Note that m_internalDispatchMap[arity] is a set with a custom comparator, which looks at function IDs not definitions
|
||||||
|
solAssert(*m_internalDispatchMap[arity].find(&_function) == &_function, "Different definitions with the same function ID");
|
||||||
|
|
||||||
|
m_internalDispatchMap[arity].insert(&_function);
|
||||||
enqueueFunctionForCodeGeneration(_function);
|
enqueueFunctionForCodeGeneration(_function);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,20 @@ namespace solidity::frontend
|
|||||||
class YulUtilFunctions;
|
class YulUtilFunctions;
|
||||||
class ABIFunctions;
|
class ABIFunctions;
|
||||||
|
|
||||||
using InternalDispatchMap = std::map<YulArity, std::set<FunctionDefinition const*>>;
|
struct AscendingFunctionIDCompare
|
||||||
|
{
|
||||||
|
bool operator()(FunctionDefinition const* _f1, FunctionDefinition const* _f2) const
|
||||||
|
{
|
||||||
|
// NULLs always first.
|
||||||
|
if (_f1 != nullptr && _f2 != nullptr)
|
||||||
|
return _f1->id() < _f2->id();
|
||||||
|
else
|
||||||
|
return _f1 == nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using DispatchSet = std::set<FunctionDefinition const*, AscendingFunctionIDCompare>;
|
||||||
|
using InternalDispatchMap = std::map<YulArity, DispatchSet>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class that contains contextual information during IR generation.
|
* Class that contains contextual information during IR generation.
|
||||||
@ -164,7 +177,7 @@ private:
|
|||||||
/// The order and duplicates are irrelevant here (hence std::set rather than std::queue) as
|
/// The order and duplicates are irrelevant here (hence std::set rather than std::queue) as
|
||||||
/// long as the order of Yul functions in the generated code is deterministic and the same on
|
/// long as the order of Yul functions in the generated code is deterministic and the same on
|
||||||
/// all platforms - which is a property guaranteed by MultiUseYulFunctionCollector.
|
/// all platforms - which is a property guaranteed by MultiUseYulFunctionCollector.
|
||||||
std::set<FunctionDefinition const*> m_functionGenerationQueue;
|
DispatchSet m_functionGenerationQueue;
|
||||||
|
|
||||||
/// Collection of functions that need to be callable via internal dispatch.
|
/// Collection of functions that need to be callable via internal dispatch.
|
||||||
/// Note that having a key with an empty set of functions is a valid situation. It means that
|
/// Note that having a key with an empty set of functions is a valid situation. It means that
|
||||||
|
Loading…
Reference in New Issue
Block a user