mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
IR codegen: Extract code for appending an internal function call into a separate function
This commit is contained in:
parent
2ca349c69a
commit
4b92cbb283
@ -47,7 +47,10 @@
|
|||||||
#include <libsolutil/FunctionSelector.h>
|
#include <libsolutil/FunctionSelector.h>
|
||||||
#include <libsolutil/Visitor.h>
|
#include <libsolutil/Visitor.h>
|
||||||
|
|
||||||
|
#include <range/v3/view/indirect.hpp>
|
||||||
|
#include <range/v3/view/addressof.hpp>
|
||||||
#include <range/v3/view/transform.hpp>
|
#include <range/v3/view/transform.hpp>
|
||||||
|
#include <range/v3/range/conversion.hpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
@ -996,42 +999,13 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
|||||||
solAssert(false, "Attempted to generate code for calling a function definition.");
|
solAssert(false, "Attempted to generate code for calling a function definition.");
|
||||||
break;
|
break;
|
||||||
case FunctionType::Kind::Internal:
|
case FunctionType::Kind::Internal:
|
||||||
{
|
solAssert(functionType);
|
||||||
FunctionDefinition const* functionDef = ASTNode::resolveFunctionCall(_functionCall, &m_context.mostDerivedContract());
|
appendInternalFunctionCall(
|
||||||
|
_functionCall,
|
||||||
solAssert(!functionType->takesArbitraryParameters());
|
*functionType,
|
||||||
|
arguments | ranges::views::indirect | ranges::views::addressof | ranges::to<vector>
|
||||||
vector<string> args;
|
);
|
||||||
if (functionType->hasBoundFirstArgument())
|
|
||||||
args += IRVariable(_functionCall.expression()).part("self").stackSlots();
|
|
||||||
|
|
||||||
for (size_t i = 0; i < arguments.size(); ++i)
|
|
||||||
args += convert(*arguments[i], *parameterTypes[i]).stackSlots();
|
|
||||||
|
|
||||||
if (functionDef)
|
|
||||||
{
|
|
||||||
solAssert(functionDef->isImplemented());
|
|
||||||
|
|
||||||
define(_functionCall) <<
|
|
||||||
m_context.enqueueFunctionForCodeGeneration(*functionDef) <<
|
|
||||||
"(" <<
|
|
||||||
joinHumanReadable(args) <<
|
|
||||||
")\n";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
YulArity arity = YulArity::fromType(*functionType);
|
|
||||||
m_context.internalFunctionCalledThroughDispatch(arity);
|
|
||||||
|
|
||||||
define(_functionCall) <<
|
|
||||||
IRNames::internalDispatch(arity) <<
|
|
||||||
"(" <<
|
|
||||||
IRVariable(_functionCall.expression()).part("functionIdentifier").name() <<
|
|
||||||
joinHumanReadablePrefixed(args) <<
|
|
||||||
")\n";
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case FunctionType::Kind::External:
|
case FunctionType::Kind::External:
|
||||||
case FunctionType::Kind::DelegateCall:
|
case FunctionType::Kind::DelegateCall:
|
||||||
appendExternalFunctionCall(_functionCall, arguments);
|
appendExternalFunctionCall(_functionCall, arguments);
|
||||||
@ -2536,6 +2510,55 @@ void IRGeneratorForStatements::handleVariableReference(
|
|||||||
solAssert(false, "Invalid variable kind.");
|
solAssert(false, "Invalid variable kind.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IRGeneratorForStatements::appendInternalFunctionCall(
|
||||||
|
FunctionCall const& _functionCall,
|
||||||
|
FunctionType const& _functionType,
|
||||||
|
vector<Expression const*> const& _arguments
|
||||||
|
)
|
||||||
|
{
|
||||||
|
solAssert(!_functionType.takesArbitraryParameters());
|
||||||
|
|
||||||
|
FunctionDefinition const *functionDefinition = ASTNode::resolveFunctionCall(_functionCall, &m_context.mostDerivedContract());
|
||||||
|
Expression const* identifierOrMemberAccess = &_functionCall.expression();
|
||||||
|
|
||||||
|
vector<string> convertedArguments;
|
||||||
|
if (_functionType.hasBoundFirstArgument())
|
||||||
|
convertedArguments += IRVariable(*identifierOrMemberAccess).part("self").stackSlots();
|
||||||
|
|
||||||
|
TypePointers parameterTypes = _functionType.parameterTypes();
|
||||||
|
for (size_t i = 0; i < _arguments.size(); ++i)
|
||||||
|
convertedArguments += convert(*_arguments[i], *parameterTypes[i]).stackSlots();
|
||||||
|
|
||||||
|
if (functionDefinition)
|
||||||
|
{
|
||||||
|
solAssert(functionDefinition->isImplemented());
|
||||||
|
if (_functionType.hasBoundFirstArgument())
|
||||||
|
solAssert(_functionType == *functionDefinition->functionType(true /* _internal */)->withBoundFirstArgument());
|
||||||
|
else
|
||||||
|
solAssert(_functionType == *functionDefinition->functionType(true /* _internal */));
|
||||||
|
|
||||||
|
define(_functionCall) <<
|
||||||
|
m_context.enqueueFunctionForCodeGeneration(*functionDefinition) <<
|
||||||
|
"(" <<
|
||||||
|
joinHumanReadable(convertedArguments) <<
|
||||||
|
")\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
solAssert(identifierOrMemberAccess);
|
||||||
|
|
||||||
|
YulArity arity = YulArity::fromType(_functionType);
|
||||||
|
m_context.internalFunctionCalledThroughDispatch(arity);
|
||||||
|
|
||||||
|
define(_functionCall) <<
|
||||||
|
IRNames::internalDispatch(arity) <<
|
||||||
|
"(" <<
|
||||||
|
IRVariable(*identifierOrMemberAccess).part("functionIdentifier").name() <<
|
||||||
|
joinHumanReadablePrefixed(convertedArguments) <<
|
||||||
|
")\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void IRGeneratorForStatements::appendExternalFunctionCall(
|
void IRGeneratorForStatements::appendExternalFunctionCall(
|
||||||
FunctionCall const& _functionCall,
|
FunctionCall const& _functionCall,
|
||||||
vector<ASTPointer<Expression const>> const& _arguments
|
vector<ASTPointer<Expression const>> const& _arguments
|
||||||
|
@ -152,6 +152,13 @@ private:
|
|||||||
Expression const& _referencingExpression
|
Expression const& _referencingExpression
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// Appends code to call an internal function with the given arguments.
|
||||||
|
/// All involved expressions have already been visited.
|
||||||
|
void appendInternalFunctionCall(
|
||||||
|
FunctionCall const& _functionCall,
|
||||||
|
FunctionType const& _functionType,
|
||||||
|
std::vector<Expression const *> const& _arguments
|
||||||
|
);
|
||||||
/// Appends code to call an external function with the given arguments.
|
/// Appends code to call an external function with the given arguments.
|
||||||
/// All involved expressions have already been visited.
|
/// All involved expressions have already been visited.
|
||||||
void appendExternalFunctionCall(
|
void appendExternalFunctionCall(
|
||||||
|
Loading…
Reference in New Issue
Block a user