From cafa01cbf60251f1e4798722e6549070972acf0a Mon Sep 17 00:00:00 2001 From: djudjuu Date: Fri, 5 Jul 2019 17:15:38 +0200 Subject: [PATCH] moved SuffixHelper to StringUtils --- libdevcore/StringUtils.cpp | 17 +++++++++++++++++ libdevcore/StringUtils.h | 6 ++++++ libsolidity/codegen/ABIFunctions.cpp | 15 ++++++++------- libsolidity/codegen/YulUtilFunctions.cpp | 19 +------------------ libsolidity/codegen/YulUtilFunctions.h | 7 ------- .../codegen/ir/IRGenerationContext.cpp | 7 ++++--- libsolidity/codegen/ir/IRGenerator.cpp | 8 ++++---- test/tools/ossfuzz/protoToYul.cpp | 14 +++++++------- 8 files changed, 47 insertions(+), 46 deletions(-) diff --git a/libdevcore/StringUtils.cpp b/libdevcore/StringUtils.cpp index e14f704e9..fd6cad339 100644 --- a/libdevcore/StringUtils.cpp +++ b/libdevcore/StringUtils.cpp @@ -96,3 +96,20 @@ string dev::quotedAlternativesList(vector 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; +} diff --git a/libdevcore/StringUtils.h b/libdevcore/StringUtils.h index 16025078e..b6deba790 100644 --- a/libdevcore/StringUtils.h +++ b/libdevcore/StringUtils.h @@ -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 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 ", " diff --git a/libsolidity/codegen/ABIFunctions.cpp b/libsolidity/codegen/ABIFunctions.cpp index 1583a8d63..2a845bfe3 100644 --- a/libsolidity/codegen/ABIFunctions.cpp +++ b/libsolidity/codegen/ABIFunctions.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -82,7 +83,7 @@ string ABIFunctions::tupleEncoder( ( add(headStart, )) )") ); - 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, ) )") ); - 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; diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index c8b2e2d03..b573c0a59 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -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(_type); diff --git a/libsolidity/codegen/YulUtilFunctions.h b/libsolidity/codegen/YulUtilFunctions.h index d9a1e4a7f..5da08dfa4 100644 --- a/libsolidity/codegen/YulUtilFunctions.h +++ b/libsolidity/codegen/YulUtilFunctions.h @@ -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); diff --git a/libsolidity/codegen/ir/IRGenerationContext.cpp b/libsolidity/codegen/ir/IRGenerationContext.cpp index 68bb20bec..73fed46bf 100644 --- a/libsolidity/codegen/ir/IRGenerationContext.cpp +++ b/libsolidity/codegen/ir/IRGenerationContext.cpp @@ -24,6 +24,7 @@ #include #include +#include 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> functions; for (auto const& contract: m_inheritanceHierarchy) for (FunctionDefinition const* function: contract->definedFunctions()) diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index 34c2bf3b3..f27130296 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -227,13 +227,13 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract) unsigned paramVars = make_shared(type->parameterTypes())->sizeOnStack(); unsigned retVars = make_shared(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(type->declaration())); templ["allocate"] = m_utils.allocationFunction(); templ["abiEncode"] = abiFunctions.tupleEncoder(type->returnParameterTypes(), type->returnParameterTypes(), false); diff --git a/test/tools/ossfuzz/protoToYul.cpp b/test/tools/ossfuzz/protoToYul.cpp index f32fda260..7d2e1b80a 100644 --- a/test/tools/ossfuzz/protoToYul.cpp +++ b/test/tools/ossfuzz/protoToYul.cpp @@ -16,13 +16,13 @@ */ #include -#include +#include #include #include 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);