mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #6348 from ethereum/varNameGenerator
ABIFunctions: Split out a function for generating a comma separated list of variable names.
This commit is contained in:
commit
58610ab3b8
@ -63,7 +63,6 @@ string ABIFunctions::tupleEncoder(
|
|||||||
templ("functionName", functionName);
|
templ("functionName", functionName);
|
||||||
size_t const headSize_ = headSize(_targetTypes);
|
size_t const headSize_ = headSize(_targetTypes);
|
||||||
templ("headSize", to_string(headSize_));
|
templ("headSize", to_string(headSize_));
|
||||||
string valueParams;
|
|
||||||
string encodeElements;
|
string encodeElements;
|
||||||
size_t headPos = 0;
|
size_t headPos = 0;
|
||||||
size_t stackPos = 0;
|
size_t stackPos = 0;
|
||||||
@ -72,13 +71,6 @@ string ABIFunctions::tupleEncoder(
|
|||||||
solAssert(_givenTypes[i], "");
|
solAssert(_givenTypes[i], "");
|
||||||
solAssert(_targetTypes[i], "");
|
solAssert(_targetTypes[i], "");
|
||||||
size_t sizeOnStack = _givenTypes[i]->sizeOnStack();
|
size_t sizeOnStack = _givenTypes[i]->sizeOnStack();
|
||||||
string valueNames = "";
|
|
||||||
for (size_t j = 0; j < sizeOnStack; j++)
|
|
||||||
{
|
|
||||||
valueNames += "value" + to_string(stackPos) + ", ";
|
|
||||||
valueParams = ", value" + to_string(stackPos) + valueParams;
|
|
||||||
stackPos++;
|
|
||||||
}
|
|
||||||
bool dynamic = _targetTypes[i]->isDynamicallyEncoded();
|
bool dynamic = _targetTypes[i]->isDynamicallyEncoded();
|
||||||
Whiskers elementTempl(
|
Whiskers elementTempl(
|
||||||
dynamic ?
|
dynamic ?
|
||||||
@ -90,14 +82,17 @@ string ABIFunctions::tupleEncoder(
|
|||||||
<abiEncode>(<values> add(headStart, <pos>))
|
<abiEncode>(<values> add(headStart, <pos>))
|
||||||
)")
|
)")
|
||||||
);
|
);
|
||||||
elementTempl("values", valueNames);
|
string values = suffixedVariableNameList("value", stackPos, stackPos + sizeOnStack);
|
||||||
|
elementTempl("values", values.empty() ? "" : values + ", ");
|
||||||
elementTempl("pos", to_string(headPos));
|
elementTempl("pos", to_string(headPos));
|
||||||
elementTempl("abiEncode", abiEncodingFunction(*_givenTypes[i], *_targetTypes[i], options));
|
elementTempl("abiEncode", abiEncodingFunction(*_givenTypes[i], *_targetTypes[i], options));
|
||||||
encodeElements += elementTempl.render();
|
encodeElements += elementTempl.render();
|
||||||
headPos += dynamic ? 0x20 : _targetTypes[i]->calldataEncodedSize();
|
headPos += dynamic ? 0x20 : _targetTypes[i]->calldataEncodedSize();
|
||||||
|
stackPos += sizeOnStack;
|
||||||
}
|
}
|
||||||
solAssert(headPos == headSize_, "");
|
solAssert(headPos == headSize_, "");
|
||||||
templ("valueParams", valueParams);
|
string valueParams = suffixedVariableNameList("value", stackPos, 0);
|
||||||
|
templ("valueParams", valueParams.empty() ? "" : ", " + valueParams);
|
||||||
templ("encodeElements", encodeElements);
|
templ("encodeElements", encodeElements);
|
||||||
|
|
||||||
return templ.render();
|
return templ.render();
|
||||||
@ -134,7 +129,6 @@ string ABIFunctions::tupleEncoderPacked(
|
|||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
templ("functionName", functionName);
|
templ("functionName", functionName);
|
||||||
string valueParams;
|
|
||||||
string encodeElements;
|
string encodeElements;
|
||||||
size_t stackPos = 0;
|
size_t stackPos = 0;
|
||||||
for (size_t i = 0; i < _givenTypes.size(); ++i)
|
for (size_t i = 0; i < _givenTypes.size(); ++i)
|
||||||
@ -142,13 +136,6 @@ string ABIFunctions::tupleEncoderPacked(
|
|||||||
solAssert(_givenTypes[i], "");
|
solAssert(_givenTypes[i], "");
|
||||||
solAssert(_targetTypes[i], "");
|
solAssert(_targetTypes[i], "");
|
||||||
size_t sizeOnStack = _givenTypes[i]->sizeOnStack();
|
size_t sizeOnStack = _givenTypes[i]->sizeOnStack();
|
||||||
string valueNames = "";
|
|
||||||
for (size_t j = 0; j < sizeOnStack; j++)
|
|
||||||
{
|
|
||||||
valueNames += "value" + to_string(stackPos) + ", ";
|
|
||||||
valueParams = ", value" + to_string(stackPos) + valueParams;
|
|
||||||
stackPos++;
|
|
||||||
}
|
|
||||||
bool dynamic = _targetTypes[i]->isDynamicallyEncoded();
|
bool dynamic = _targetTypes[i]->isDynamicallyEncoded();
|
||||||
Whiskers elementTempl(
|
Whiskers elementTempl(
|
||||||
dynamic ?
|
dynamic ?
|
||||||
@ -160,13 +147,16 @@ string ABIFunctions::tupleEncoderPacked(
|
|||||||
pos := add(pos, <calldataEncodedSize>)
|
pos := add(pos, <calldataEncodedSize>)
|
||||||
)")
|
)")
|
||||||
);
|
);
|
||||||
elementTempl("values", valueNames);
|
string values = suffixedVariableNameList("value", stackPos, stackPos + sizeOnStack);
|
||||||
|
elementTempl("values", values.empty() ? "" : values + ", ");
|
||||||
if (!dynamic)
|
if (!dynamic)
|
||||||
elementTempl("calldataEncodedSize", to_string(_targetTypes[i]->calldataEncodedSize(false)));
|
elementTempl("calldataEncodedSize", to_string(_targetTypes[i]->calldataEncodedSize(false)));
|
||||||
elementTempl("abiEncode", abiEncodingFunction(*_givenTypes[i], *_targetTypes[i], options));
|
elementTempl("abiEncode", abiEncodingFunction(*_givenTypes[i], *_targetTypes[i], options));
|
||||||
encodeElements += elementTempl.render();
|
encodeElements += elementTempl.render();
|
||||||
|
stackPos += sizeOnStack;
|
||||||
}
|
}
|
||||||
templ("valueParams", valueParams);
|
string valueParams = suffixedVariableNameList("value", stackPos, 0);
|
||||||
|
templ("valueParams", valueParams.empty() ? "" : ", " + valueParams);
|
||||||
templ("encodeElements", encodeElements);
|
templ("encodeElements", encodeElements);
|
||||||
|
|
||||||
return templ.render();
|
return templ.render();
|
||||||
@ -636,29 +626,32 @@ string ABIFunctions::abiEncodeAndReturnUpdatedPosFunction(
|
|||||||
_targetType.identifier() +
|
_targetType.identifier() +
|
||||||
_options.toFunctionNameSuffix();
|
_options.toFunctionNameSuffix();
|
||||||
return createFunction(functionName, [&]() {
|
return createFunction(functionName, [&]() {
|
||||||
|
string values = suffixedVariableNameList("value", 0, numVariablesForType(_givenType, _options));
|
||||||
string encoder = abiEncodingFunction(_givenType, _targetType, _options);
|
string encoder = abiEncodingFunction(_givenType, _targetType, _options);
|
||||||
if (_targetType.isDynamicallyEncoded())
|
if (_targetType.isDynamicallyEncoded())
|
||||||
return Whiskers(R"(
|
return Whiskers(R"(
|
||||||
function <functionName>(value, pos) -> updatedPos {
|
function <functionName>(<values>, pos) -> updatedPos {
|
||||||
updatedPos := <encode>(value, pos)
|
updatedPos := <encode>(<values>, pos)
|
||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
("encode", encoder)
|
("encode", encoder)
|
||||||
|
("values", values)
|
||||||
.render();
|
.render();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned encodedSize = _targetType.calldataEncodedSize(_options.padded);
|
unsigned encodedSize = _targetType.calldataEncodedSize(_options.padded);
|
||||||
solAssert(encodedSize != 0, "Invalid encoded size.");
|
solAssert(encodedSize != 0, "Invalid encoded size.");
|
||||||
return Whiskers(R"(
|
return Whiskers(R"(
|
||||||
function <functionName>(value, pos) -> updatedPos {
|
function <functionName>(<values>, pos) -> updatedPos {
|
||||||
<encode>(value, pos)
|
<encode>(<values>, pos)
|
||||||
updatedPos := add(pos, <encodedSize>)
|
updatedPos := add(pos, <encodedSize>)
|
||||||
}
|
}
|
||||||
)")
|
)")
|
||||||
("functionName", functionName)
|
("functionName", functionName)
|
||||||
("encode", encoder)
|
("encode", encoder)
|
||||||
("encodedSize", toCompactHexWithPrefix(encodedSize))
|
("encodedSize", toCompactHexWithPrefix(encodedSize))
|
||||||
|
("values", values)
|
||||||
.render();
|
.render();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1566,3 +1559,28 @@ size_t ABIFunctions::headSize(TypePointers const& _targetTypes)
|
|||||||
return headSize;
|
return headSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string ABIFunctions::suffixedVariableNameList(string const& _baseName, size_t _startSuffix, size_t _endSuffix)
|
||||||
|
{
|
||||||
|
string result;
|
||||||
|
if (_startSuffix < _endSuffix)
|
||||||
|
{
|
||||||
|
result = _baseName + to_string(_startSuffix++);
|
||||||
|
while (_startSuffix < _endSuffix)
|
||||||
|
result += ", " + _baseName + to_string(_startSuffix++);
|
||||||
|
}
|
||||||
|
else if (_endSuffix < _startSuffix)
|
||||||
|
{
|
||||||
|
result = _baseName + to_string(_endSuffix++);
|
||||||
|
while (_endSuffix < _startSuffix)
|
||||||
|
result = _baseName + to_string(_endSuffix++) + ", " + result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ABIFunctions::numVariablesForType(Type const& _type, EncodingOptions const& _options)
|
||||||
|
{
|
||||||
|
if (_type.category() == Type::Category::Function && !_options.encodeFunctionFromStack)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return _type.sizeOnStack();
|
||||||
|
}
|
||||||
|
@ -253,6 +253,18 @@ private:
|
|||||||
/// @returns the size of the static part of the encoding of the given types.
|
/// @returns the size of the static part of the encoding of the given types.
|
||||||
static size_t headSize(TypePointers const& _targetTypes);
|
static size_t headSize(TypePointers const& _targetTypes);
|
||||||
|
|
||||||
|
/// @returns a string containing a comma-separated list of variable names consisting of @a _baseName suffixed
|
||||||
|
/// with increasing integers in the range [@a _startSuffix, @a _endSuffix), if @a _startSuffix < @a _endSuffix,
|
||||||
|
/// and with decreasing integers in the range [@a _endSuffix, @a _startSuffix), if @a _endSuffix < @a _startSuffix.
|
||||||
|
/// If @a _startSuffix == @a _endSuffix, the empty string is returned.
|
||||||
|
static std::string suffixedVariableNameList(std::string const& _baseName, size_t _startSuffix, size_t _endSuffix);
|
||||||
|
|
||||||
|
/// @returns the number of variables needed to store a type.
|
||||||
|
/// This is one for almost all types. The exception being dynamically sized calldata arrays or
|
||||||
|
/// external function types (if we are encoding from stack, i.e. _options.encodeFunctionFromStack
|
||||||
|
/// is true), for which it is two.
|
||||||
|
static size_t numVariablesForType(Type const& _type, EncodingOptions const& _options);
|
||||||
|
|
||||||
langutil::EVMVersion m_evmVersion;
|
langutil::EVMVersion m_evmVersion;
|
||||||
std::shared_ptr<MultiUseYulFunctionCollector> m_functionCollector;
|
std::shared_ptr<MultiUseYulFunctionCollector> m_functionCollector;
|
||||||
std::set<std::string> m_externallyUsedFunctions;
|
std::set<std::string> m_externallyUsedFunctions;
|
||||||
|
Loading…
Reference in New Issue
Block a user