mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #8949 from ethereum/sol-yul-refactor-add-arity
[Sol->Yul] Add Arity struct (refactor)
This commit is contained in:
commit
d7b434fc6b
@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include <libsolidity/codegen/ir/Common.h>
|
||||
#include <libsolidity/ast/TypeProvider.h>
|
||||
|
||||
#include <libsolutil/CommonIO.h>
|
||||
|
||||
@ -23,6 +24,13 @@ using namespace std;
|
||||
using namespace solidity::util;
|
||||
using namespace solidity::frontend;
|
||||
|
||||
YulArity YulArity::fromType(FunctionType const& _functionType)
|
||||
{
|
||||
return YulArity{
|
||||
TupleType(_functionType.parameterTypes()).sizeOnStack(),
|
||||
TupleType(_functionType.returnParameterTypes()).sizeOnStack()
|
||||
};
|
||||
}
|
||||
string IRNames::function(FunctionDefinition const& _function)
|
||||
{
|
||||
// @TODO previously, we had to distinguish creation context and runtime context,
|
||||
|
@ -22,11 +22,28 @@
|
||||
|
||||
#include <libsolidity/ast/AST.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
namespace solidity::frontend
|
||||
{
|
||||
|
||||
/**
|
||||
* Structure that describes arity and co-arity of a Yul function, i.e. the number of its inputs and outputs.
|
||||
*/
|
||||
struct YulArity
|
||||
{
|
||||
explicit YulArity(size_t _in, size_t _out): in(_in), out(_out) {}
|
||||
|
||||
static YulArity fromType(FunctionType const& _functionType);
|
||||
|
||||
bool operator==(YulArity const& _other) const { return in == _other.in && out == _other.out; }
|
||||
bool operator!=(YulArity const& _other) const { return !(*this == _other); }
|
||||
|
||||
size_t in; /// Number of input parameters
|
||||
size_t out; /// Number of output parameters
|
||||
};
|
||||
|
||||
struct IRNames
|
||||
{
|
||||
static std::string function(FunctionDefinition const& _function);
|
||||
@ -45,3 +62,15 @@ struct IRNames
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// Overloading std::less() makes it possible to use YulArity as a map key. We could define operator<
|
||||
// instead but such an operator would be a bit ambiguous (e.g. YulArity{2, 2} would be be greater than
|
||||
// YulArity{1, 10} in lexicographical order but the latter has greater total number of inputs and outputs).
|
||||
template<>
|
||||
struct std::less<solidity::frontend::YulArity>
|
||||
{
|
||||
bool operator() (solidity::frontend::YulArity const& _lhs, solidity::frontend::YulArity const& _rhs) const
|
||||
{
|
||||
return _lhs.in < _rhs.in || (_lhs.in == _rhs.in && _lhs.out < _rhs.out);
|
||||
}
|
||||
};
|
||||
|
@ -121,9 +121,9 @@ string IRGenerationContext::newYulVariable()
|
||||
return "_" + to_string(++m_varCounter);
|
||||
}
|
||||
|
||||
string IRGenerationContext::internalDispatch(size_t _in, size_t _out)
|
||||
string IRGenerationContext::internalDispatch(YulArity const& _arity)
|
||||
{
|
||||
string funName = "dispatch_internal_in_" + to_string(_in) + "_out_" + to_string(_out);
|
||||
string funName = "dispatch_internal_in_" + to_string(_arity.in) + "_out_" + to_string(_arity.out);
|
||||
return m_functions.createFunction(funName, [&]() {
|
||||
Whiskers templ(R"(
|
||||
function <functionName>(fun <comma> <in>) <arrow> <out> {
|
||||
@ -138,12 +138,12 @@ string IRGenerationContext::internalDispatch(size_t _in, size_t _out)
|
||||
}
|
||||
)");
|
||||
templ("functionName", funName);
|
||||
templ("comma", _in > 0 ? "," : "");
|
||||
templ("comma", _arity.in > 0 ? "," : "");
|
||||
YulUtilFunctions utils(m_evmVersion, m_revertStrings, m_functions);
|
||||
templ("in", suffixedVariableNameList("in_", 0, _in));
|
||||
templ("arrow", _out > 0 ? "->" : "");
|
||||
templ("assignment_op", _out > 0 ? ":=" : "");
|
||||
templ("out", suffixedVariableNameList("out_", 0, _out));
|
||||
templ("in", suffixedVariableNameList("in_", 0, _arity.in));
|
||||
templ("arrow", _arity.out > 0 ? "->" : "");
|
||||
templ("assignment_op", _arity.out > 0 ? ":=" : "");
|
||||
templ("out", suffixedVariableNameList("out_", 0, _arity.out));
|
||||
|
||||
// UNIMPLEMENTED: Internal library calls via pointers are not implemented yet.
|
||||
// We're not generating code for internal library functions here even though it's possible
|
||||
@ -153,10 +153,8 @@ string IRGenerationContext::internalDispatch(size_t _in, size_t _out)
|
||||
for (auto const& contract: mostDerivedContract().annotation().linearizedBaseContracts)
|
||||
for (FunctionDefinition const* function: contract->definedFunctions())
|
||||
if (
|
||||
FunctionType const* functionType = TypeProvider::function(*function, FunctionType::Kind::Internal);
|
||||
!function->isConstructor() &&
|
||||
TupleType(functionType->parameterTypes()).sizeOnStack() == _in &&
|
||||
TupleType(functionType->returnParameterTypes()).sizeOnStack() == _out
|
||||
YulArity::fromType(*TypeProvider::function(*function, FunctionType::Kind::Internal)) == _arity
|
||||
)
|
||||
{
|
||||
// 0 is reserved for uninitialized function pointers
|
||||
|
@ -102,7 +102,7 @@ public:
|
||||
|
||||
std::string newYulVariable();
|
||||
|
||||
std::string internalDispatch(size_t _in, size_t _out);
|
||||
std::string internalDispatch(YulArity const& _arity);
|
||||
|
||||
/// @returns a new copy of the utility function generator (but using the same function set).
|
||||
YulUtilFunctions utils();
|
||||
|
@ -692,16 +692,16 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
||||
joinHumanReadable(args) <<
|
||||
")\n";
|
||||
else
|
||||
{
|
||||
YulArity arity = YulArity::fromType(*functionType);
|
||||
define(_functionCall) <<
|
||||
// NOTE: internalDispatch() takes care of adding the function to function generation queue
|
||||
m_context.internalDispatch(
|
||||
TupleType(functionType->parameterTypes()).sizeOnStack(),
|
||||
TupleType(functionType->returnParameterTypes()).sizeOnStack()
|
||||
) <<
|
||||
m_context.internalDispatch(arity) <<
|
||||
"(" <<
|
||||
IRVariable(_functionCall.expression()).part("functionIdentifier").name() <<
|
||||
joinHumanReadablePrefixed(args) <<
|
||||
")\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FunctionType::Kind::External:
|
||||
|
Loading…
Reference in New Issue
Block a user