Skip to content

Commit 5a68eaf

Browse files
committed
Deduplicate the logic between function calls and binary operations
1 parent 0977921 commit 5a68eaf

File tree

3 files changed

+28
-21
lines changed

3 files changed

+28
-21
lines changed

Diff for: libsolidity/ast/AST.h

+3
Original file line numberDiff line numberDiff line change
@@ -2162,6 +2162,9 @@ class BinaryOperation: public Expression
21622162
Expression const& rightExpression() const { return *m_right; }
21632163
Token getOperator() const { return m_operator; }
21642164

2165+
/// @returns the given arguments in the order they were written.
2166+
std::vector<ASTPointer<Expression const>> arguments() const { return {m_left, m_right}; }
2167+
21652168
FunctionType const* userDefinedFunctionType() const;
21662169

21672170
BinaryOperationAnnotation& annotation() const override;

Diff for: libsolidity/experimental/codegen/IRGeneratorForStatements.cpp

+23-21
Original file line numberDiff line numberDiff line change
@@ -201,16 +201,31 @@ void IRGeneratorForStatements::endVisit(BinaryOperation const& _binaryOperation)
201201
Type functionType = helper.functionType(helper.tupleType({leftType, rightType}), resultType);
202202
auto [typeClass, memberName] = m_context.analysis.annotation<TypeInference>().operators.at(_binaryOperation.getOperator());
203203
auto const& functionDefinition = resolveTypeClassFunction(typeClass, memberName, functionType);
204-
// TODO: deduplicate with FunctionCall
205-
// TODO: get around resolveRecursive by passing the environment further down?
206-
functionType = m_context.env->resolveRecursive(functionType);
207-
m_context.enqueueFunctionDefinition(&functionDefinition, functionType);
208204
std::string functionDeclaration = var(_binaryOperation).commaSeparatedList();
209205
if (!functionDeclaration.empty())
210206
m_code << "let " << functionDeclaration << " := ";
211-
m_code << IRNames::function(*m_context.env, functionDefinition, functionType) << "(" <<
212-
var(_binaryOperation.leftExpression()).commaSeparatedList() <<
213-
var(_binaryOperation.rightExpression()).commaSeparatedListPrefixed() << ")\n";
207+
m_code << buildFunctionCall(functionDefinition, functionType, _binaryOperation.arguments());
208+
}
209+
210+
std::string IRGeneratorForStatements::buildFunctionCall(FunctionDefinition const& _functionDefinition, Type _functionType, std::vector<ASTPointer<Expression const>> const& _arguments)
211+
{
212+
// Ensure type is resolved
213+
// TODO: get around resolveRecursive by passing the environment further down?
214+
Type resolvedFunctionType = m_context.env->resolveRecursive(_functionType);
215+
m_context.enqueueFunctionDefinition(&_functionDefinition, resolvedFunctionType);
216+
217+
std::ostringstream output;
218+
output << IRNames::function(*m_context.env, _functionDefinition, resolvedFunctionType) << "(";
219+
if (_arguments.size() == 1)
220+
output << var(*_arguments.back()).commaSeparatedList();
221+
else if (_arguments.size() > 1)
222+
{
223+
for (auto arg: _arguments | ranges::views::drop_last(1))
224+
output << var(*arg).commaSeparatedList();
225+
output << var(*_arguments.back()).commaSeparatedListPrefixed();
226+
}
227+
output << ")\n";
228+
return output.str();
214229
}
215230

216231
void IRGeneratorForStatements::declareAssign(IRVariable const& _lhs, IRVariable const& _rhs, bool _declare)
@@ -341,25 +356,12 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
341356
}
342357
FunctionDefinition const* functionDefinition = dynamic_cast<FunctionDefinition const*>(std::get<Declaration const*>(declaration));
343358
solAssert(functionDefinition);
344-
// TODO: get around resolveRecursive by passing the environment further down?
345-
functionType = m_context.env->resolveRecursive(functionType);
346-
m_context.enqueueFunctionDefinition(functionDefinition, functionType);
347359
// TODO: account for return stack size
348360
solAssert(!functionDefinition->returnParameterList());
349361
std::string functionDeclaration = var(_functionCall).commaSeparatedList();
350362
if (!functionDeclaration.empty())
351363
m_code << "let " << var(_functionCall).commaSeparatedList() << " := ";
352-
m_code << IRNames::function(*m_context.env, *functionDefinition, functionType) << "(";
353-
auto const& arguments = _functionCall.arguments();
354-
if (arguments.size() == 1)
355-
m_code << var(*arguments.back()).commaSeparatedList();
356-
else if (arguments.size() > 1)
357-
{
358-
for (auto arg: arguments | ranges::views::drop_last(1))
359-
m_code << var(*arg).commaSeparatedList();
360-
m_code << var(*arguments.back()).commaSeparatedListPrefixed();
361-
}
362-
m_code << ")\n";
364+
m_code << buildFunctionCall(*functionDefinition, functionType, _functionCall.arguments());
363365
}
364366

365367
bool IRGeneratorForStatements::visit(FunctionCall const&)

Diff for: libsolidity/experimental/codegen/IRGeneratorForStatements.h

+2
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ class IRGeneratorForStatements: public ASTConstVisitor
133133
};
134134
std::map<Expression const*, std::variant<Declaration const*, Builtins>> m_expressionDeclaration;
135135

136+
std::string buildFunctionCall(FunctionDefinition const& _functionDefinition, Type _functionType, std::vector<ASTPointer<Expression const>> const& _arguments);
137+
136138
template<typename IRVariableType>
137139
IRVariable var(IRVariableType const& _var) const
138140
{

0 commit comments

Comments
 (0)