moved SuffixHelper to StringUtils

This commit is contained in:
djudjuu 2019-07-05 17:15:38 +02:00
parent 019ec63f63
commit cafa01cbf6
8 changed files with 47 additions and 46 deletions

View File

@ -96,3 +96,20 @@ string dev::quotedAlternativesList(vector<string> const& suggestions)
return joinHumanReadable(quotedSuggestions, ", ", " or ");
}
string dev::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;
}

View File

@ -39,6 +39,12 @@ size_t stringDistance(std::string const& _str1, std::string const& _str2);
// Return a string having elements of suggestions as quoted, alternative suggestions. e.g. "a", "b" or "c"
std::string quotedAlternativesList(std::vector<std::string> const& suggestions);
/// @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.
std::string suffixedVariableNameList(std::string const& _baseName, size_t _startSuffix, size_t _endSuffix);
/// Joins collection of strings into one string with separators between, last separator can be different.
/// @param _list collection of strings to join
/// @param _separator defaults to ", "

View File

@ -24,6 +24,7 @@
#include <libsolidity/codegen/CompilerUtils.h>
#include <libdevcore/Whiskers.h>
#include <libdevcore/StringUtils.h>
#include <boost/algorithm/string/join.hpp>
#include <boost/range/adaptor/reversed.hpp>
@ -82,7 +83,7 @@ string ABIFunctions::tupleEncoder(
<abiEncode>(<values> add(headStart, <pos>))
)")
);
string values = m_utils.suffixedVariableNameList("value", stackPos, stackPos + sizeOnStack);
string values = suffixedVariableNameList("value", stackPos, stackPos + sizeOnStack);
elementTempl("values", values.empty() ? "" : values + ", ");
elementTempl("pos", to_string(headPos));
elementTempl("abiEncode", abiEncodingFunction(*_givenTypes[i], *_targetTypes[i], options));
@ -91,7 +92,7 @@ string ABIFunctions::tupleEncoder(
stackPos += sizeOnStack;
}
solAssert(headPos == headSize_, "");
string valueParams = m_utils.suffixedVariableNameList("value", stackPos, 0);
string valueParams = suffixedVariableNameList("value", stackPos, 0);
templ("valueParams", valueParams.empty() ? "" : ", " + valueParams);
templ("encodeElements", encodeElements);
@ -147,7 +148,7 @@ string ABIFunctions::tupleEncoderPacked(
pos := add(pos, <calldataEncodedSize>)
)")
);
string values = m_utils.suffixedVariableNameList("value", stackPos, stackPos + sizeOnStack);
string values = suffixedVariableNameList("value", stackPos, stackPos + sizeOnStack);
elementTempl("values", values.empty() ? "" : values + ", ");
if (!dynamic)
elementTempl("calldataEncodedSize", to_string(_targetTypes[i]->calldataEncodedSize(false)));
@ -155,7 +156,7 @@ string ABIFunctions::tupleEncoderPacked(
encodeElements += elementTempl.render();
stackPos += sizeOnStack;
}
string valueParams = m_utils.suffixedVariableNameList("value", stackPos, 0);
string valueParams = suffixedVariableNameList("value", stackPos, 0);
templ("valueParams", valueParams.empty() ? "" : ", " + valueParams);
templ("encodeElements", encodeElements);
@ -367,7 +368,7 @@ string ABIFunctions::abiEncodeAndReturnUpdatedPosFunction(
_targetType.identifier() +
_options.toFunctionNameSuffix();
return createFunction(functionName, [&]() {
string values = m_utils.suffixedVariableNameList("value", 0, numVariablesForType(_givenType, _options));
string values = suffixedVariableNameList("value", 0, numVariablesForType(_givenType, _options));
string encoder = abiEncodingFunction(_givenType, _targetType, _options);
if (_targetType.isDynamicallyEncoded())
return Whiskers(R"(
@ -508,7 +509,7 @@ string ABIFunctions::abiEncodingFunctionSimpleArray(
EncodingOptions subOptions(_options);
subOptions.encodeFunctionFromStack = false;
subOptions.padded = true;
string elementValues = m_utils.suffixedVariableNameList("elementValue", 0, numVariablesForType(*_from.baseType(), subOptions));
string elementValues = suffixedVariableNameList("elementValue", 0, numVariablesForType(*_from.baseType(), subOptions));
Whiskers templ(
usesTail ?
R"(
@ -892,7 +893,7 @@ string ABIFunctions::abiEncodingFunctionStruct(
// Like with arrays, struct members are always padded.
subOptions.padded = true;
string memberValues = m_utils.suffixedVariableNameList("memberValue", 0, numVariablesForType(*memberTypeFrom, subOptions));
string memberValues = suffixedVariableNameList("memberValue", 0, numVariablesForType(*memberTypeFrom, subOptions));
members.back()["memberValues"] = memberValues;
string encode;

View File

@ -24,6 +24,7 @@
#include <libsolidity/ast/AST.h>
#include <libsolidity/codegen/CompilerUtils.h>
#include <libdevcore/Whiskers.h>
#include <libdevcore/StringUtils.h>
#include <boost/algorithm/string/join.hpp>
#include <boost/range/adaptor/reversed.hpp>
@ -1399,24 +1400,6 @@ string YulUtilFunctions::forwardingRevertFunction()
});
}
string YulUtilFunctions::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;
}
std::string YulUtilFunctions::decrementCheckedFunction(Type const& _type)
{
IntegerType const& type = dynamic_cast<IntegerType const&>(_type);

View File

@ -224,13 +224,6 @@ public:
/// as reason string.
std::string forwardingRevertFunction();
/// @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);
std::string incrementCheckedFunction(Type const& _type);
std::string decrementCheckedFunction(Type const& _type);

View File

@ -24,6 +24,7 @@
#include <libsolidity/ast/AST.h>
#include <libdevcore/Whiskers.h>
#include <libdevcore/StringUtils.h>
using namespace dev;
using namespace dev::solidity;
@ -98,7 +99,7 @@ string IRGenerationContext::variable(Expression const& _expression)
if (size == 1)
return var;
else
return YulUtilFunctions::suffixedVariableNameList(move(var) + "_", 1, 1 + size);
return suffixedVariableNameList(move(var) + "_", 1, 1 + size);
}
string IRGenerationContext::variablePart(Expression const& _expression, size_t _part)
@ -128,9 +129,9 @@ string IRGenerationContext::internalDispatch(size_t _in, size_t _out)
templ("functionName", funName);
templ("comma", _in > 0 ? "," : "");
YulUtilFunctions utils(m_evmVersion, m_functions);
templ("in", utils.suffixedVariableNameList("in_", 0, _in));
templ("in", suffixedVariableNameList("in_", 0, _in));
templ("arrow", _out > 0 ? "->" : "");
templ("out", utils.suffixedVariableNameList("out_", 0, _out));
templ("out", suffixedVariableNameList("out_", 0, _out));
vector<map<string, string>> functions;
for (auto const& contract: m_inheritanceHierarchy)
for (FunctionDefinition const* function: contract->definedFunctions())

View File

@ -227,13 +227,13 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract)
unsigned paramVars = make_shared<TupleType>(type->parameterTypes())->sizeOnStack();
unsigned retVars = make_shared<TupleType>(type->returnParameterTypes())->sizeOnStack();
templ["assignToParams"] = paramVars == 0 ? "" : "let " + m_utils.suffixedVariableNameList("param_", 0, paramVars) + " := ";
templ["assignToRetParams"] = retVars == 0 ? "" : "let " + m_utils.suffixedVariableNameList("ret_", 0, retVars) + " := ";
templ["assignToParams"] = paramVars == 0 ? "" : "let " + suffixedVariableNameList("param_", 0, paramVars) + " := ";
templ["assignToRetParams"] = retVars == 0 ? "" : "let " + suffixedVariableNameList("ret_", 0, retVars) + " := ";
ABIFunctions abiFunctions(m_evmVersion, m_context.functionCollector());
templ["abiDecode"] = abiFunctions.tupleDecoder(type->parameterTypes());
templ["params"] = m_utils.suffixedVariableNameList("param_", 0, paramVars);
templ["retParams"] = m_utils.suffixedVariableNameList("ret_", retVars, 0);
templ["params"] = suffixedVariableNameList("param_", 0, paramVars);
templ["retParams"] = suffixedVariableNameList("ret_", retVars, 0);
templ["function"] = generateFunction(dynamic_cast<FunctionDefinition const&>(type->declaration()));
templ["allocate"] = m_utils.allocationFunction();
templ["abiEncode"] = abiFunctions.tupleEncoder(type->returnParameterTypes(), type->returnParameterTypes(), false);

View File

@ -16,13 +16,13 @@
*/
#include <test/tools/ossfuzz/protoToYul.h>
#include <libsolidity/codegen/YulUtilFunctions.h>
#include <libdevcore/StringUtils.h>
#include <boost/range/algorithm_ext/erase.hpp>
#include <libyul/Exceptions.h>
using namespace std;
using namespace yul::test::yul_fuzzer;
using namespace dev::solidity;
using namespace dev;
string ProtoConverter::createHex(string const& _hexBytes) const
{
@ -250,7 +250,7 @@ void ProtoConverter::visit(MultiVarDecl const& _x)
// (k-p)+1 = numOutParams
m_output <<
"let " <<
YulUtilFunctions::suffixedVariableNameList("x_", m_numLiveVars, m_numLiveVars + numOutParams) <<
dev::suffixedVariableNameList("x_", m_numLiveVars, m_numLiveVars + numOutParams) <<
" := ";
// Create RHS of multi var decl
@ -887,7 +887,7 @@ void ProtoConverter::createFunctionDefAndCall(T const& _x, unsigned _numInParams
m_output << "function foo_" << functionTypeToString(_type) << "_" << m_numFunctionSets;
m_output << "(";
if (_numInParams > 0)
m_output << YulUtilFunctions::suffixedVariableNameList("x_", 0, _numInParams);
m_output << dev::suffixedVariableNameList("x_", 0, _numInParams);
m_output << ")";
// Book keeping for variables in function scope and in nested scopes
@ -897,7 +897,7 @@ void ProtoConverter::createFunctionDefAndCall(T const& _x, unsigned _numInParams
// This creates -> x_n+1,...,x_r
if (_numOutParams > 0)
{
m_output << " -> " << YulUtilFunctions::suffixedVariableNameList("x_", _numInParams, _numInParams + _numOutParams);
m_output << " -> " << dev::suffixedVariableNameList("x_", _numInParams, _numInParams + _numOutParams);
// More bookkeeping
m_numVarsPerScope.top() += _numOutParams;
m_numLiveVars += _numOutParams;
@ -915,7 +915,7 @@ void ProtoConverter::createFunctionDefAndCall(T const& _x, unsigned _numInParams
// Manually create a multi assignment using global variables
// This prints a_0, ..., a_k-1 for this function that returns "k" values
if (_numOutParams > 0)
m_output << YulUtilFunctions::suffixedVariableNameList("a_", 0, _numOutParams) << " := ";
m_output << dev::suffixedVariableNameList("a_", 0, _numOutParams) << " := ";
// Call the function with the correct number of input parameters via calls to calldataload with
// incremental addresses.
@ -976,7 +976,7 @@ void ProtoConverter::visit(Program const& _x)
m_output << "{\n";
// Create globals at the beginning
// This creates let a_0, a_1, a_2, a_3 (followed by a new line)
m_output << "let " << YulUtilFunctions::suffixedVariableNameList("a_", 0, modOutputParams - 1) << "\n";
m_output << "let " << dev::suffixedVariableNameList("a_", 0, modOutputParams - 1) << "\n";
// Register function interface. Useful while visiting multi var decl/assignment statements.
for (auto const& f: _x.funcs())
registerFunction(f);