diff --git a/libsolidity/codegen/ir/IRGenerationContext.cpp b/libsolidity/codegen/ir/IRGenerationContext.cpp index 7476dd90e..eff854efd 100644 --- a/libsolidity/codegen/ir/IRGenerationContext.cpp +++ b/libsolidity/codegen/ir/IRGenerationContext.cpp @@ -137,38 +137,20 @@ void IRGenerationContext::initializeInternalDispatch(InternalDispatchMap _intern InternalDispatchMap IRGenerationContext::consumeInternalDispatchMap() { - m_directInternalFunctionCalls.clear(); - InternalDispatchMap internalDispatch = move(m_internalDispatchMap); m_internalDispatchMap.clear(); return internalDispatch; } -void IRGenerationContext::internalFunctionCalledDirectly(Expression const& _expression) +void IRGenerationContext::addToInternalDispatch(FunctionDefinition const& _function) { - solAssert(m_directInternalFunctionCalls.count(&_expression) == 0, ""); + FunctionType const* functionType = TypeProvider::function(_function, FunctionType::Kind::Internal); + solAssert(functionType, ""); - m_directInternalFunctionCalls.insert(&_expression); + m_internalDispatchMap[YulArity::fromType(*functionType)].insert(&_function); + enqueueFunctionForCodeGeneration(_function); } -void IRGenerationContext::internalFunctionAccessed(Expression const& _expression, FunctionDefinition const& _function) -{ - solAssert( - IRHelpers::referencedFunctionDeclaration(_expression) && - _function.resolveVirtual(mostDerivedContract()) == - IRHelpers::referencedFunctionDeclaration(_expression)->resolveVirtual(mostDerivedContract()), - "Function definition does not match the expression" - ); - - if (m_directInternalFunctionCalls.count(&_expression) == 0) - { - FunctionType const* functionType = TypeProvider::function(_function, FunctionType::Kind::Internal); - solAssert(functionType, ""); - - m_internalDispatchMap[YulArity::fromType(*functionType)].insert(&_function); - enqueueFunctionForCodeGeneration(_function); - } -} void IRGenerationContext::internalFunctionCalledThroughDispatch(YulArity const& _arity) { diff --git a/libsolidity/codegen/ir/IRGenerationContext.h b/libsolidity/codegen/ir/IRGenerationContext.h index 8f102dfda..900bde7c5 100644 --- a/libsolidity/codegen/ir/IRGenerationContext.h +++ b/libsolidity/codegen/ir/IRGenerationContext.h @@ -108,7 +108,7 @@ public: void initializeInternalDispatch(InternalDispatchMap _internalDispatchMap); InternalDispatchMap consumeInternalDispatchMap(); - bool internalDispatchClean() const { return m_internalDispatchMap.empty() && m_directInternalFunctionCalls.empty(); } + bool internalDispatchClean() const { return m_internalDispatchMap.empty(); } /// Notifies the context that a function call that needs to go through internal dispatch was /// encountered while visiting the AST. This ensures that the corresponding dispatch function @@ -116,16 +116,8 @@ public: /// the code contains a call to an uninitialized function variable). void internalFunctionCalledThroughDispatch(YulArity const& _arity); - /// Notifies the context that a direct function call (i.e. not through internal dispatch) was - /// encountered while visiting the AST. This lets the context know that the function should - /// not be added to the dispatch (unless there are also indirect calls to it elsewhere else). - void internalFunctionCalledDirectly(Expression const& _expression); - - /// Notifies the context that a name representing an internal function has been found while - /// visiting the AST. If the name has not been reported as a direct call using - /// @a internalFunctionCalledDirectly(), it's assumed to represent function variable access - /// and the function gets added to internal dispatch. - void internalFunctionAccessed(Expression const& _expression, FunctionDefinition const& _function); + /// Adds a function to the internal dispatch. + void addToInternalDispatch(FunctionDefinition const& _function); /// @returns a new copy of the utility function generator (but using the same function set). YulUtilFunctions utils(); @@ -179,7 +171,6 @@ private: /// the code contains a call via a pointer even though a specific function is never assigned to it. /// It will fail at runtime but the code must still compile. InternalDispatchMap m_internalDispatchMap; - std::set m_directInternalFunctionCalls; std::set m_subObjects; }; diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 5e75f1d17..5fe28919d 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -804,20 +804,6 @@ bool IRGeneratorForStatements::visit(BinaryOperation const& _binOp) return false; } -bool IRGeneratorForStatements::visit(FunctionCall const& _functionCall) -{ - setLocation(_functionCall); - FunctionTypePointer functionType = dynamic_cast(&type(_functionCall.expression())); - if ( - functionType && - functionType->kind() == FunctionType::Kind::Internal && - IRHelpers::referencedFunctionDeclaration(_functionCall.expression()) - ) - m_context.internalFunctionCalledDirectly(_functionCall.expression()); - - return true; -} - void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) { setLocation(_functionCall); @@ -1557,6 +1543,7 @@ void IRGeneratorForStatements::endVisit(FunctionCallOptions const& _options) void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) { setLocation(_memberAccess); + ASTString const& member = _memberAccess.memberName(); auto memberFunctionType = dynamic_cast(_memberAccess.annotation().type); Type::Category objectCategory = _memberAccess.expression().annotation().type->category(); @@ -1582,7 +1569,8 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) if (memberFunctionType->kind() == FunctionType::Kind::Internal) { define(IRVariable(_memberAccess).part("functionIdentifier")) << to_string(functionDefinition.id()) << "\n"; - m_context.internalFunctionAccessed(_memberAccess, functionDefinition); + if (!_memberAccess.annotation().calledDirectly) + m_context.addToInternalDispatch(functionDefinition); } else { @@ -1612,7 +1600,9 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) define(_memberAccess) << to_string(resolvedFunctionDef.id()) << "\n"; solAssert(resolvedFunctionDef.functionType(true), ""); solAssert(resolvedFunctionDef.functionType(true)->kind() == FunctionType::Kind::Internal, ""); - m_context.internalFunctionAccessed(_memberAccess, resolvedFunctionDef); + + if (!_memberAccess.annotation().calledDirectly) + m_context.addToInternalDispatch(resolvedFunctionDef); } // ordinary contract type else if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration) @@ -1876,7 +1866,8 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) if (auto const* function = dynamic_cast(_memberAccess.annotation().referencedDeclaration)) { define(_memberAccess) << to_string(function->id()) << "\n"; - m_context.internalFunctionAccessed(_memberAccess, *function); + if (!_memberAccess.annotation().calledDirectly) + m_context.addToInternalDispatch(*function); } else solAssert(false, "Function not found in member access"); @@ -1956,7 +1947,9 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) solAssert(*_memberAccess.annotation().requiredLookup == VirtualLookup::Static, ""); define(_memberAccess) << to_string(function->id()) << "\n"; - m_context.internalFunctionAccessed(_memberAccess, *function); + + if (!_memberAccess.annotation().calledDirectly) + m_context.addToInternalDispatch(*function); } break; } @@ -2198,7 +2191,8 @@ void IRGeneratorForStatements::endVisit(Identifier const& _identifier) solAssert(resolvedFunctionDef.functionType(true), ""); solAssert(resolvedFunctionDef.functionType(true)->kind() == FunctionType::Kind::Internal, ""); - m_context.internalFunctionAccessed(_identifier, resolvedFunctionDef); + if (!_identifier.annotation().calledDirectly) + m_context.addToInternalDispatch(resolvedFunctionDef); } else if (VariableDeclaration const* varDecl = dynamic_cast(declaration)) handleVariableReference(*varDecl, _identifier); diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.h b/libsolidity/codegen/ir/IRGeneratorForStatements.h index 21386dd6c..19201a827 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.h +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.h @@ -74,7 +74,6 @@ public: void endVisit(Return const& _return) override; void endVisit(UnaryOperation const& _unaryOperation) override; bool visit(BinaryOperation const& _binOp) override; - bool visit(FunctionCall const& _funCall) override; void endVisit(FunctionCall const& _funCall) override; void endVisit(FunctionCallOptions const& _funCallOptions) override; void endVisit(MemberAccess const& _memberAccess) override;