diff --git a/libsolidity/codegen/ABIFunctions.cpp b/libsolidity/codegen/ABIFunctions.cpp index 9f244fdb1..03ff14cc2 100644 --- a/libsolidity/codegen/ABIFunctions.cpp +++ b/libsolidity/codegen/ABIFunctions.cpp @@ -1541,5 +1541,5 @@ size_t ABIFunctions::numVariablesForType(Type const& _type, EncodingOptions cons std::string ABIFunctions::revertReasonIfDebug(std::string const& _message) { - return YulUtilFunctions::revertReasonIfDebug(m_revertStrings, _message); + return m_utils.revertReasonIfDebugAssembly(m_revertStrings, _message); } diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index fea449f7f..1b7f50509 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -529,7 +529,7 @@ LinkerObject const& CompilerContext::assembledObject() const string CompilerContext::revertReasonIfDebug(string const& _message) { - return YulUtilFunctions::revertReasonIfDebug(m_revertStrings, _message); + return m_yulUtilFunctions.revertReasonIfDebugAssembly(m_revertStrings, _message); } void CompilerContext::updateSourceLocation() diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index f7d9711a2..f1b05a339 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -1159,8 +1159,8 @@ string YulUtilFunctions::calldataArrayIndexRangeAccess(ArrayType const& _type) )") ("functionName", functionName) ("stride", to_string(_type.calldataStride())) - ("revertSliceStartAfterEnd", revertReasonIfDebug("Slice starts after end")) - ("revertSliceGreaterThanLength", revertReasonIfDebug("Slice is greater than length")) + ("revertSliceStartAfterEnd", revertReasonIfDebugAssembly(m_revertStrings, "Slice starts after end")) + ("revertSliceGreaterThanLength", revertReasonIfDebugAssembly(m_revertStrings, "Slice is greater than length")) .render(); }); } @@ -1188,9 +1188,9 @@ string YulUtilFunctions::accessCalldataTailFunction(Type const& _type) ("dynamicallySized", _type.isDynamicallySized()) ("neededLength", toCompactHexWithPrefix(_type.calldataEncodedTailSize())) ("calldataStride", toCompactHexWithPrefix(_type.isDynamicallySized() ? dynamic_cast(_type).calldataStride() : 0)) - ("invalidCalldataTailOffset", revertReasonIfDebug("Invalid calldata tail offset")) - ("invalidCalldataTailLength", revertReasonIfDebug("Invalid calldata tail length")) - ("shortCalldataTail", revertReasonIfDebug("Calldata tail too short")) + ("invalidCalldataTailOffset", revertReasonIfDebugAssembly(m_revertStrings, "Invalid calldata tail offset")) + ("invalidCalldataTailLength", revertReasonIfDebugAssembly(m_revertStrings, "Invalid calldata tail length")) + ("shortCalldataTail", revertReasonIfDebugAssembly(m_revertStrings, "Calldata tail too short")) .render(); }); } @@ -2495,11 +2495,10 @@ string YulUtilFunctions::readFromMemoryOrCalldata(Type const& _type, bool _fromC }); } -string YulUtilFunctions::revertReasonIfDebug(RevertStrings revertStrings, string const& _message) +string YulUtilFunctions::revertReasonIfDebugAssembly(RevertStrings _revertStrings, std::string const& _message) { - if (revertStrings >= RevertStrings::Debug && !_message.empty()) - { - Whiskers templ(R"({ + Whiskers templ(R"({ + mstore(0, ) mstore(4, 0x20) mstore(add(4, 0x20), ) @@ -2508,29 +2507,56 @@ string YulUtilFunctions::revertReasonIfDebug(RevertStrings revertStrings, string mstore(add(reasonPos, ), ) revert(0, add(reasonPos, )) - })"); - templ("sig", (u256(util::FixedHash<4>::Arith(util::FixedHash<4>(util::keccak256("Error(string)")))) << (256 - 32)).str()); + + revert(0, 0) + + })"); + bool debugAndMessage = _revertStrings >= RevertStrings::Debug && !_message.empty(); + templ("debugAndMessage", debugAndMessage); + if (debugAndMessage) + { + templ("sig", (u256(util::FixedHash<4>::Arith(util::FixedHash<4>(util::keccak256("Error(string)")))) + << (256 - 32)).str()); templ("length", to_string(_message.length())); size_t words = (_message.length() + 31) / 32; vector> wordParams(words); - for (size_t i = 0; i < words; ++i) - { + for (size_t i = 0; i < words; ++i) { wordParams[i]["offset"] = to_string(i * 32); wordParams[i]["wordValue"] = formatAsStringOrNumber(_message.substr(32 * i, 32)); } templ("word", wordParams); templ("end", to_string(words * 32)); - - return templ.render(); } - else - return "revert(0, 0)"; + + return templ.render(); } -string YulUtilFunctions::revertReasonIfDebug(string const& _message) +string YulUtilFunctions::revertReasonIfDebugFunction(RevertStrings _revertStrings, string const& _message) { - return revertReasonIfDebug(m_revertStrings, _message); + string functionName = "revert_reason_" + revertStringsToString(_revertStrings) + "_"; + for (char c: _message) + if (isalnum(c)) + functionName += tolower(c); + else if (isspace(c)) + functionName += "_"; + + return m_functionCollector.createFunction(functionName, [&]() { + Whiskers templ(R"({ + function () { + + } + })"); + templ("functionName", functionName); + templ("revertReasonAssembly", revertReasonIfDebugAssembly(_revertStrings, _message)); + + return templ.render(); + }); +} + +string YulUtilFunctions::revertReasonIfDebugFunction(string const& _message) +{ + return revertReasonIfDebugFunction(m_revertStrings, _message); } string YulUtilFunctions::tryDecodeErrorMessageFunction() diff --git a/libsolidity/codegen/YulUtilFunctions.h b/libsolidity/codegen/YulUtilFunctions.h index c23a7d735..ff5b8d04c 100644 --- a/libsolidity/codegen/YulUtilFunctions.h +++ b/libsolidity/codegen/YulUtilFunctions.h @@ -335,9 +335,11 @@ public: /// If revertStrings is debug, @returns inline assembly code that /// stores @param _message in memory position 0 and reverts. /// Otherwise returns "revert(0, 0)". - static std::string revertReasonIfDebug(RevertStrings revertStrings, std::string const& _message = ""); + std::string revertReasonIfDebugAssembly(RevertStrings revertStrings, std::string const& _message = ""); - std::string revertReasonIfDebug(std::string const& _message = ""); + std::string revertReasonIfDebugFunction(RevertStrings revertStrings, std::string const& _message = ""); + + std::string revertReasonIfDebugFunction(std::string const& _message = ""); /// Returns the name of a function that decodes an error message. /// signature: () -> arrayPtr diff --git a/libsolidity/codegen/ir/IRGenerationContext.cpp b/libsolidity/codegen/ir/IRGenerationContext.cpp index b85e2f7d3..da1e7eb85 100644 --- a/libsolidity/codegen/ir/IRGenerationContext.cpp +++ b/libsolidity/codegen/ir/IRGenerationContext.cpp @@ -186,5 +186,5 @@ ABIFunctions IRGenerationContext::abiFunctions() std::string IRGenerationContext::revertReasonIfDebug(std::string const& _message) { - return YulUtilFunctions::revertReasonIfDebug(m_revertStrings, _message); + return utils().revertReasonIfDebugFunction(m_revertStrings, _message) + "()"; } diff --git a/test/cmdlineTests/standard_irOptimized_requested/output.json b/test/cmdlineTests/standard_irOptimized_requested/output.json index ba3cb8b2a..72bf57edd 100644 --- a/test/cmdlineTests/standard_irOptimized_requested/output.json +++ b/test/cmdlineTests/standard_irOptimized_requested/output.json @@ -36,7 +36,7 @@ object \"C_6\" { revert(0, 0) function abi_decode_tuple_(headStart, dataEnd) { - if slt(sub(dataEnd, headStart), 0) { revert(0, 0) } + if slt(sub(dataEnd, headStart), 0) { { revert(0, 0) } } } function abi_encode_tuple__to__fromStack(headStart) -> tail { tail := add(headStart, 0) } diff --git a/test/cmdlineTests/standard_ir_requested/output.json b/test/cmdlineTests/standard_ir_requested/output.json index f63075090..728c7dcdc 100644 --- a/test/cmdlineTests/standard_ir_requested/output.json +++ b/test/cmdlineTests/standard_ir_requested/output.json @@ -48,7 +48,11 @@ object \"C_6\" { revert(0, 0) function abi_decode_tuple_(headStart, dataEnd) { - if slt(sub(dataEnd, headStart), 0) { revert(0, 0) } + if slt(sub(dataEnd, headStart), 0) { { + + revert(0, 0) + + } } } diff --git a/test/cmdlineTests/yul_string_format_ascii/output.json b/test/cmdlineTests/yul_string_format_ascii/output.json index 0609704c5..b6298a49b 100644 --- a/test/cmdlineTests/yul_string_format_ascii/output.json +++ b/test/cmdlineTests/yul_string_format_ascii/output.json @@ -48,7 +48,11 @@ object \"C_10\" { revert(0, 0) function abi_decode_tuple_(headStart, dataEnd) { - if slt(sub(dataEnd, headStart), 0) { revert(0, 0) } + if slt(sub(dataEnd, headStart), 0) { { + + revert(0, 0) + + } } } diff --git a/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json b/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json index 1bc00b338..f3605b998 100644 --- a/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json +++ b/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json @@ -48,7 +48,11 @@ object \"C_10\" { revert(0, 0) function abi_decode_tuple_(headStart, dataEnd) { - if slt(sub(dataEnd, headStart), 0) { revert(0, 0) } + if slt(sub(dataEnd, headStart), 0) { { + + revert(0, 0) + + } } } diff --git a/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json b/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json index fdef77781..88c97516f 100644 --- a/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json +++ b/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json @@ -48,7 +48,11 @@ object \"C_10\" { revert(0, 0) function abi_decode_tuple_(headStart, dataEnd) { - if slt(sub(dataEnd, headStart), 0) { revert(0, 0) } + if slt(sub(dataEnd, headStart), 0) { { + + revert(0, 0) + + } } } diff --git a/test/cmdlineTests/yul_string_format_ascii_long/output.json b/test/cmdlineTests/yul_string_format_ascii_long/output.json index 2a845796d..2d1416b79 100644 --- a/test/cmdlineTests/yul_string_format_ascii_long/output.json +++ b/test/cmdlineTests/yul_string_format_ascii_long/output.json @@ -48,7 +48,11 @@ object \"C_10\" { revert(0, 0) function abi_decode_tuple_(headStart, dataEnd) { - if slt(sub(dataEnd, headStart), 0) { revert(0, 0) } + if slt(sub(dataEnd, headStart), 0) { { + + revert(0, 0) + + } } } diff --git a/test/cmdlineTests/yul_string_format_hex/output.json b/test/cmdlineTests/yul_string_format_hex/output.json index 784baf2f4..0d6e91440 100644 --- a/test/cmdlineTests/yul_string_format_hex/output.json +++ b/test/cmdlineTests/yul_string_format_hex/output.json @@ -48,7 +48,11 @@ object \"C_10\" { revert(0, 0) function abi_decode_tuple_(headStart, dataEnd) { - if slt(sub(dataEnd, headStart), 0) { revert(0, 0) } + if slt(sub(dataEnd, headStart), 0) { { + + revert(0, 0) + + } } }