Skip to content

Commit 9be5754

Browse files
authored
Merge pull request #11470 from ethereum/cacheVirtualLookup
Cache functions by name.
2 parents a30cf6c + 0d948eb commit 9be5754

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

libsolidity/ast/AST.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,17 @@ FunctionDefinition const* ContractDefinition::nextConstructor(ContractDefinition
276276
return nullptr;
277277
}
278278

279+
multimap<std::string, FunctionDefinition const*> const& ContractDefinition::definedFunctionsByName() const
280+
{
281+
return m_definedFunctionsByName.init([&]{
282+
std::multimap<std::string, FunctionDefinition const*> result;
283+
for (FunctionDefinition const* fun: filteredNodes<FunctionDefinition>(m_subNodes))
284+
result.insert({fun->name(), fun});
285+
return result;
286+
});
287+
}
288+
289+
279290
TypeNameAnnotation& TypeName::annotation() const
280291
{
281292
return initAnnotation<TypeNameAnnotation>();
@@ -397,6 +408,7 @@ FunctionDefinition const& FunctionDefinition::resolveVirtual(
397408
) const
398409
{
399410
solAssert(!isConstructor(), "");
411+
solAssert(!name().empty(), "");
400412

401413
// If we are not doing super-lookup and the function is not virtual, we can stop here.
402414
if (_searchStart == nullptr && !virtualSemantics())
@@ -416,10 +428,8 @@ FunctionDefinition const& FunctionDefinition::resolveVirtual(
416428
else
417429
foundSearchStart = true;
418430

419-
for (FunctionDefinition const* function: c->definedFunctions())
431+
for (FunctionDefinition const* function: c->definedFunctions(name()))
420432
if (
421-
function->name() == name() &&
422-
!function->isConstructor() &&
423433
// With super lookup analysis guarantees that there is an implemented function in the chain.
424434
// With virtual lookup there are valid cases where returning an unimplemented one is fine.
425435
(function->isImplemented() || _searchStart == nullptr) &&

libsolidity/ast/AST.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636

3737
#include <json/json.h>
3838

39+
#include <range/v3/view/subrange.hpp>
40+
#include <range/v3/view/map.hpp>
41+
3942
#include <memory>
4043
#include <optional>
4144
#include <string>
@@ -497,6 +500,13 @@ class ContractDefinition: public Declaration, public StructurallyDocumented, pub
497500
std::vector<VariableDeclaration const*> stateVariables() const { return filteredNodes<VariableDeclaration>(m_subNodes); }
498501
std::vector<ModifierDefinition const*> functionModifiers() const { return filteredNodes<ModifierDefinition>(m_subNodes); }
499502
std::vector<FunctionDefinition const*> definedFunctions() const { return filteredNodes<FunctionDefinition>(m_subNodes); }
503+
/// @returns a view<FunctionDefinition const*> of all functions
504+
/// defined in this contract of the given name (excluding inherited functions).
505+
auto definedFunctions(std::string const& _name) const
506+
{
507+
auto&& [b, e] = definedFunctionsByName().equal_range(_name);
508+
return ranges::subrange<decltype(b)>(b, e) | ranges::views::values;
509+
}
500510
std::vector<EventDefinition const*> events() const { return filteredNodes<EventDefinition>(m_subNodes); }
501511
std::vector<EventDefinition const*> const& interfaceEvents() const;
502512
/// @returns all errors defined in this contract or any base contract
@@ -546,13 +556,16 @@ class ContractDefinition: public Declaration, public StructurallyDocumented, pub
546556
FunctionDefinition const* nextConstructor(ContractDefinition const& _mostDerivedContract) const;
547557

548558
private:
559+
std::multimap<std::string, FunctionDefinition const*> const& definedFunctionsByName() const;
560+
549561
std::vector<ASTPointer<InheritanceSpecifier>> m_baseContracts;
550562
std::vector<ASTPointer<ASTNode>> m_subNodes;
551563
ContractKind m_contractKind;
552564
bool m_abstract{false};
553565

554566
util::LazyInit<std::vector<std::pair<util::FixedHash<4>, FunctionTypePointer>>> m_interfaceFunctionList[2];
555567
util::LazyInit<std::vector<EventDefinition const*>> m_interfaceEvents;
568+
util::LazyInit<std::multimap<std::string, FunctionDefinition const*>> m_definedFunctionsByName;
556569
};
557570

558571
/**

0 commit comments

Comments
 (0)