From 94f97169ab9a288d0ea4d8e49e0798855a20a3e7 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Thu, 15 Feb 2024 21:47:11 +0100 Subject: [PATCH] [yul] Add support for parsing debug data attributes. --- liblangutil/DebugData.h | 16 +- libsolutil/CMakeLists.txt | 1 + libsolutil/Cache.h | 126 +++++++++++++ libyul/AsmParser.cpp | 148 ++++++++++++++-- libyul/AsmParser.h | 32 +++- test/CMakeLists.txt | 1 + .../ethdebug_large_debug_attributes/args | 1 + .../ethdebug_large_debug_attributes/input.yul | 16 ++ .../ethdebug_large_debug_attributes/output | 26 +++ test/libsolutil/Cache.cpp | 166 ++++++++++++++++++ test/libyul/Parser.cpp | 66 ++++++- .../invalid/invalid_debug_merge.yul | 7 + .../invalid/invalid_debug_patch.yul | 7 + .../invalid_debug_patch_patch_object.yul | 7 + .../invalid/invalid_debug_set.yul | 7 + 15 files changed, 599 insertions(+), 28 deletions(-) create mode 100644 libsolutil/Cache.h create mode 100644 test/cmdlineTests/ethdebug_large_debug_attributes/args create mode 100644 test/cmdlineTests/ethdebug_large_debug_attributes/input.yul create mode 100644 test/cmdlineTests/ethdebug_large_debug_attributes/output create mode 100644 test/libsolutil/Cache.cpp create mode 100644 test/libyul/yulSyntaxTests/invalid/invalid_debug_merge.yul create mode 100644 test/libyul/yulSyntaxTests/invalid/invalid_debug_patch.yul create mode 100644 test/libyul/yulSyntaxTests/invalid/invalid_debug_patch_patch_object.yul create mode 100644 test/libyul/yulSyntaxTests/invalid/invalid_debug_set.yul diff --git a/liblangutil/DebugData.h b/liblangutil/DebugData.h index 70259bd039f3..9e58d9f37794 100644 --- a/liblangutil/DebugData.h +++ b/liblangutil/DebugData.h @@ -19,6 +19,7 @@ #pragma once #include +#include #include #include @@ -28,27 +29,32 @@ namespace solidity::langutil struct DebugData { typedef typename std::shared_ptr ConstPtr; + typedef std::optional>> Attributes; explicit DebugData( langutil::SourceLocation _nativeLocation = {}, langutil::SourceLocation _originLocation = {}, - std::optional _astID = {} + std::optional _astID = {}, + Attributes _attributes = {} ): nativeLocation(std::move(_nativeLocation)), originLocation(std::move(_originLocation)), - astID(_astID) + astID(_astID), + attributes(std::move(_attributes)) {} static DebugData::ConstPtr create( langutil::SourceLocation _nativeLocation, langutil::SourceLocation _originLocation = {}, - std::optional _astID = {} + std::optional _astID = {}, + Attributes _attributes = {} ) { return std::make_shared( std::move(_nativeLocation), std::move(_originLocation), - _astID + _astID, + std::move(_attributes) ); } @@ -65,6 +71,8 @@ struct DebugData langutil::SourceLocation originLocation; /// ID in the (Solidity) source AST. std::optional astID; + /// Additional debug data attributes. + Attributes attributes; }; } // namespace solidity::langutil diff --git a/libsolutil/CMakeLists.txt b/libsolutil/CMakeLists.txt index a1e9559edef0..7382cbbc3b61 100644 --- a/libsolutil/CMakeLists.txt +++ b/libsolutil/CMakeLists.txt @@ -2,6 +2,7 @@ set(sources Algorithms.h AnsiColorized.h Assertions.h + Cache.h Common.h CommonData.cpp CommonData.h diff --git a/libsolutil/Cache.h b/libsolutil/Cache.h new file mode 100644 index 000000000000..4ec1e2e0aa95 --- /dev/null +++ b/libsolutil/Cache.h @@ -0,0 +1,126 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 +/** @file Cache.h + * @date 2024 + * + * Simple cache. + */ + +#pragma once + +#include + +#include +#include +#include + +#include + +#include + +namespace solidity::util +{ + +namespace detail +{ + +template typename TCache ,typename THash, typename TValue> +class CacheBase +{ +public: + typedef THash Hash; + typedef TValue Value; + typedef TCache Cache; + typedef std::shared_ptr Entry; + typedef std::shared_ptr Ptr; + + Entry set(Hash const& hash, Value const& value) + { + Entry result; + if (m_cache.find(hash) == m_cache.end()) + { + result = std::make_shared(value); + auto [_, inserted] = m_cache.emplace(std::make_pair(hash, result)); + solAssert(inserted); + } + else + result = m_cache[hash]; + return result; + } + + Entry set(Value const& value) { return set(Cache::hash(value), value); } + + std::map const& cache() { return m_cache; } + + typename std::map::iterator get(Hash const& hash) { return m_cache.find(hash); } + + typename std::map::iterator begin() { return m_cache.begin(); } + + typename std::map::iterator end() { return m_cache.end(); } + +private: + std::map m_cache; +}; + +} // namespace detail + +template +class Cache; + +template +class Cache: public detail::CacheBase +{ +public: + static size_t hash(TValue const& value) + { + boost::hash hasher; + return hasher(value); + } +}; + +template +class Cache: public detail::CacheBase +{ +public: + static h256 hash(TValue const& value) + { + std::stringstream stream; + stream << value; + return keccak256(stream.str()); + } +}; + +template<> +class Cache: public detail::CacheBase +{ +public: + static size_t hash(Json const& value) + { + boost::hash hasher; + return hasher(value.dump(0)); + } +}; + +template<> +class Cache: public detail::CacheBase +{ +public: + static h256 hash(Json const& value) { return keccak256(value.dump(0)); } +}; + +} // namespace solidity::util diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index d41b41a36a42..f6df876dd3da 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -62,14 +62,36 @@ std::optional toInt(std::string const& _value) langutil::DebugData::ConstPtr Parser::createDebugData() const { + solAssert(m_debugAttributeCache); switch (m_useSourceLocationFrom) { - case UseSourceLocationFrom::Scanner: - return DebugData::create(ParserBase::currentLocation(), ParserBase::currentLocation()); - case UseSourceLocationFrom::LocationOverride: - return DebugData::create(m_locationOverride, m_locationOverride); - case UseSourceLocationFrom::Comments: - return DebugData::create(ParserBase::currentLocation(), m_locationFromComment, m_astIDFromComment); + case UseSourceLocationFrom::Scanner: + return DebugData::create( + ParserBase::currentLocation(), + ParserBase::currentLocation(), + {}, + m_currentDebugAttributes.has_value() + ? DebugData::Attributes({m_debugAttributeCache->set(*m_currentDebugAttributes)}) + : DebugData::Attributes({}) + ); + case UseSourceLocationFrom::LocationOverride: + return DebugData::create( + m_locationOverride, + m_locationOverride, + {}, + m_currentDebugAttributes.has_value() + ? DebugData::Attributes({m_debugAttributeCache->set(*m_currentDebugAttributes)}) + : DebugData::Attributes({}) + ); + case UseSourceLocationFrom::Comments: + return DebugData::create( + ParserBase::currentLocation(), + m_locationFromComment, + m_astIDFromComment, + m_currentDebugAttributes.has_value() + ? DebugData::Attributes({m_debugAttributeCache->set(*m_currentDebugAttributes)}) + : DebugData::Attributes({}) + ); } solAssert(false, ""); } @@ -138,24 +160,20 @@ std::unique_ptr Parser::parseInline(std::shared_ptr const& _scanne langutil::Token Parser::advance() { auto const token = ParserBase::advance(); - if (m_useSourceLocationFrom == UseSourceLocationFrom::Comments) - fetchDebugDataFromComment(); + fetchDebugDataFromComment(); return token; } void Parser::fetchDebugDataFromComment() { - solAssert(m_sourceNames.has_value(), ""); - static std::regex const tagRegex = std::regex( - R"~~((?:^|\s+)(@[a-zA-Z0-9\-_]+)(?:\s+|$))~~", // tag, e.g: @src + R"~~((?:^|\s+)(@[a-zA-Z0-9\-\._]+)(?:\s+|$))~~", // tag, e.g: @src std::regex_constants::ECMAScript | std::regex_constants::optimize ); std::string_view commentLiteral = m_scanner->currentCommentLiteral(); std::match_results match; - langutil::SourceLocation originLocation = m_locationFromComment; // Empty for each new node. std::optional astID; @@ -166,10 +184,14 @@ void Parser::fetchDebugDataFromComment() if (match[1] == "@src") { - if (auto parseResult = parseSrcComment(commentLiteral, m_scanner->currentCommentLocation())) - tie(commentLiteral, originLocation) = *parseResult; - else - break; + if (m_useSourceLocationFrom == UseSourceLocationFrom::Comments) + { + solAssert(m_sourceNames.has_value(), ""); + if (auto parseResult = parseSrcComment(commentLiteral, m_scanner->currentCommentLocation())) + tie(commentLiteral, m_locationFromComment) = *parseResult; + else + break; + } } else if (match[1] == "@ast-id") { @@ -178,15 +200,107 @@ void Parser::fetchDebugDataFromComment() else break; } + else if (match[1] == "@debug.set") + { + if (auto parseResult = parseDebugDataAttributeOperationComment(match[1], commentLiteral, m_scanner->currentCommentLocation())) + { + commentLiteral = parseResult->first; + if (parseResult->second.has_value()) + m_currentDebugAttributes = parseResult->second.value(); + } + else + break; + } + else if (match[1] == "@debug.merge") + { + if (auto parseResult = parseDebugDataAttributeOperationComment(match[1], commentLiteral, m_scanner->currentCommentLocation())) + { + commentLiteral = parseResult->first; + if (parseResult->second.has_value()) + { + if (!m_currentDebugAttributes.has_value()) + m_currentDebugAttributes = Json::object(); + m_currentDebugAttributes->merge_patch(parseResult->second.value()); + } + } + else + break; + } + else if (match[1] == "@debug.patch") + { + if (auto parseResult = parseDebugDataAttributeOperationComment(match[1], commentLiteral, m_scanner->currentCommentLocation())) + { + commentLiteral = parseResult->first; + if (parseResult->second.has_value()) + applyDebugDataAttributePatch(parseResult->second.value(), m_scanner->currentCommentLocation()); + } + else + break; + } else // Ignore unrecognized tags. continue; } - m_locationFromComment = originLocation; m_astIDFromComment = astID; } +std::optional>> Parser::parseDebugDataAttributeOperationComment( + std::string const& _command, + std::string_view _arguments, + langutil::SourceLocation const& _location +) +{ + std::optional jsonData; + try + { + jsonData = Json::parse(_arguments.begin(), _arguments.end(), nullptr, true); + } + catch (nlohmann::json::parse_error& e) + { + try + { + jsonData = Json::parse(_arguments.substr(0, e.byte - 1), nullptr, true); + } + catch(nlohmann::json::parse_error& ee) + { + m_errorReporter.syntaxError( + 5721_error, + _location, + _command + ": Could not parse debug data: " + removeNlohmannInternalErrorIdentifier(ee.what()) + ); + jsonData.reset(); + } + _arguments = _arguments.substr(e.byte - 1); + } + return {{_arguments, jsonData}}; +} + +void Parser::applyDebugDataAttributePatch(Json const& _jsonPatch, langutil::SourceLocation const& _location) +{ + try + { + if (!m_currentDebugAttributes.has_value()) + m_currentDebugAttributes = Json::object(); + if (_jsonPatch.is_object()) + { + Json array = Json::array(); + array.push_back(_jsonPatch); + m_currentDebugAttributes = m_currentDebugAttributes->patch(array); + } + else + m_currentDebugAttributes = m_currentDebugAttributes->patch(_jsonPatch); + } + catch(nlohmann::json::parse_error& ee) + { + m_errorReporter.syntaxError( + 9426_error, + _location, + "@debug.patch: Could not patch debug data: " + removeNlohmannInternalErrorIdentifier(ee.what()) + ); + } +} + std::optional> Parser::parseSrcComment( std::string_view const _arguments, langutil::SourceLocation const& _commentLocation diff --git a/libyul/AsmParser.h b/libyul/AsmParser.h index d4616a2a9508..e4a6b51bd9fe 100644 --- a/libyul/AsmParser.h +++ b/libyul/AsmParser.h @@ -31,10 +31,11 @@ #include #include +#include + #include #include #include -#include #include namespace solidity::yul @@ -43,6 +44,8 @@ namespace solidity::yul class Parser: public langutil::ParserBase { public: + typedef util::Cache DebugAttributeCache; + enum class ForLoopComponent { None, ForLoopPre, ForLoopPost, ForLoopBody @@ -56,7 +59,8 @@ class Parser: public langutil::ParserBase explicit Parser( langutil::ErrorReporter& _errorReporter, Dialect const& _dialect, - std::optional _locationOverride = {} + std::optional _locationOverride = {}, + DebugAttributeCache::Ptr debugAttributesCache = {} ): ParserBase(_errorReporter), m_dialect(_dialect), @@ -65,7 +69,8 @@ class Parser: public langutil::ParserBase _locationOverride ? UseSourceLocationFrom::LocationOverride : UseSourceLocationFrom::Scanner - } + }, + m_debugAttributeCache(debugAttributesCache == nullptr ? std::make_shared() : debugAttributesCache) {} /// Constructs a Yul parser that is using the debug data @@ -73,7 +78,8 @@ class Parser: public langutil::ParserBase explicit Parser( langutil::ErrorReporter& _errorReporter, Dialect const& _dialect, - std::optional>> _sourceNames + std::optional>> _sourceNames, + DebugAttributeCache::Ptr debugAttributesCache = {} ): ParserBase(_errorReporter), m_dialect(_dialect), @@ -82,7 +88,8 @@ class Parser: public langutil::ParserBase m_sourceNames.has_value() ? UseSourceLocationFrom::Comments : UseSourceLocationFrom::Scanner - } + }, + m_debugAttributeCache(debugAttributesCache == nullptr ? std::make_shared() : debugAttributesCache) {} /// Parses an inline assembly block starting with `{` and ending with `}`. @@ -117,6 +124,14 @@ class Parser: public langutil::ParserBase langutil::SourceLocation const& _commentLocation ); + std::optional>> parseDebugDataAttributeOperationComment( + std::string const& _command, + std::string_view _arguments, + langutil::SourceLocation const& _commentLocation + ); + + void applyDebugDataAttributePatch(Json const& _jsonPatch, langutil::SourceLocation const& _location); + /// Creates a DebugData object with the correct source location set. langutil::DebugData::ConstPtr createDebugData() const; @@ -154,6 +169,11 @@ class Parser: public langutil::ParserBase static bool isValidNumberLiteral(std::string const& _literal); + DebugAttributeCache::Ptr debugAttributeCache() const + { + return m_debugAttributeCache; + } + private: Dialect const& m_dialect; @@ -164,6 +184,8 @@ class Parser: public langutil::ParserBase UseSourceLocationFrom m_useSourceLocationFrom = UseSourceLocationFrom::Scanner; ForLoopComponent m_currentForLoopComponent = ForLoopComponent::None; bool m_insideFunction = false; + std::optional m_currentDebugAttributes; + mutable DebugAttributeCache::Ptr m_debugAttributeCache; }; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5308a55f7826..1a3cb4950257 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -28,6 +28,7 @@ set(contracts_sources detect_stray_source_files("${contracts_sources}" "contracts/") set(libsolutil_sources + libsolutil/Cache.cpp libsolutil/Checksum.cpp libsolutil/CommonData.cpp libsolutil/CommonIO.cpp diff --git a/test/cmdlineTests/ethdebug_large_debug_attributes/args b/test/cmdlineTests/ethdebug_large_debug_attributes/args new file mode 100644 index 000000000000..2c89c24e0a35 --- /dev/null +++ b/test/cmdlineTests/ethdebug_large_debug_attributes/args @@ -0,0 +1 @@ +--strict-assembly diff --git a/test/cmdlineTests/ethdebug_large_debug_attributes/input.yul b/test/cmdlineTests/ethdebug_large_debug_attributes/input.yul new file mode 100644 index 000000000000..42b90b56d3ba --- /dev/null +++ b/test/cmdlineTests/ethdebug_large_debug_attributes/input.yul @@ -0,0 +1,16 @@ +object "a" { + code { + /// @debug.set { + /// "A": "B", + /// "C": "........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", + /// "D": "........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................" + /// } + let addr := linkersymbol("contract/test.sol:L") + /// @debug.merge { + /// "E": "........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", + /// "F": "G", + /// "H": "........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................" + /// } + sstore(0, addr) + } +} diff --git a/test/cmdlineTests/ethdebug_large_debug_attributes/output b/test/cmdlineTests/ethdebug_large_debug_attributes/output new file mode 100644 index 000000000000..ad74f2ebeede --- /dev/null +++ b/test/cmdlineTests/ethdebug_large_debug_attributes/output @@ -0,0 +1,26 @@ + +======= ethdebug_large_debug_attributes/input.yul (EVM) ======= + +Pretty printed source: +object "a" { + code { + { + let addr := linkersymbol("contract/test.sol:L") + sstore(0, addr) + } + } +} + + +Binary representation: +73__$f919ba91ac99f96129544b80b9516b27a8$__5f5500 + +Text representation: + /* "ethdebug_large_debug_attributes/input.yul":54152:54187 */ + linkerSymbol("f919ba91ac99f96129544b80b9516b27a80e376b9dc693819d0b18b7e0395612") + /* "ethdebug_large_debug_attributes/input.yul":108313:108314 */ + 0x00 + /* "ethdebug_large_debug_attributes/input.yul":108306:108321 */ + sstore + /* "ethdebug_large_debug_attributes/input.yul":22:108327 */ + stop diff --git a/test/libsolutil/Cache.cpp b/test/libsolutil/Cache.cpp new file mode 100644 index 000000000000..eba1f62f887b --- /dev/null +++ b/test/libsolutil/Cache.cpp @@ -0,0 +1,166 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 +/** + * @date 2024 + * Unit tests for libsolutil/Cache.h. + */ + +#include +#include + +#include + +#include + + +namespace solidity::util::test +{ + +BOOST_AUTO_TEST_SUITE(CacheTest, *boost::unit_test::label("nooptions")) + +BOOST_AUTO_TEST_CASE(smoke_test) +{ + Cache::Entry cached_int; + Cache int_cache; + cached_int = int_cache.set(45); + BOOST_CHECK(int_cache.set(45) == cached_int); + BOOST_CHECK(int_cache.set(46) == int_cache.set(46)); + + Cache h256_int_cache; + cached_int = h256_int_cache.set(45); + BOOST_CHECK(h256_int_cache.set(45) == cached_int); + BOOST_CHECK(h256_int_cache.set(46) == h256_int_cache.set(46)); + + Cache string_cache; + std::shared_ptr cached_string = string_cache.set(""); + BOOST_CHECK(string_cache.set("") == cached_string); + BOOST_CHECK(string_cache.set("hello") == string_cache.set("hello")); + + Cache h256_string_cache; + cached_string = h256_string_cache.set(""); + BOOST_CHECK(h256_string_cache.set("") == cached_string); + BOOST_CHECK(h256_string_cache.set("hello") == h256_string_cache.set("hello")); + + Cache h256_json_cache; + Cache::Entry cached_json = h256_json_cache.set({}); + BOOST_CHECK(h256_json_cache.set({}) == cached_json); + BOOST_CHECK(h256_json_cache.set({{"a", "b"}}) == h256_json_cache.set({{"a", "b"}})); + + Cache json_cache; + cached_json = json_cache.set({}); + BOOST_CHECK(json_cache.set({}) == cached_json); + BOOST_CHECK(json_cache.set({{"a", "b"}}) == json_cache.set({{"a", "b"}})); + + Cache::Ptr json_cache_ptr = std::make_shared>(); + cached_json = json_cache_ptr->set({}); + BOOST_CHECK(json_cache_ptr->set({}) == cached_json); + BOOST_CHECK(json_cache_ptr->set({{"a", "b"}}) == json_cache_ptr->set({{"a", "b"}})); + + Cache::Ptr h256_json_cache_ptr = std::make_shared>(); + cached_json = h256_json_cache_ptr->set({}); + BOOST_CHECK(h256_json_cache_ptr->set({}) == cached_json); + BOOST_CHECK(h256_json_cache_ptr->set({{"a", "b"}}) == h256_json_cache_ptr->set({{"a", "b"}})); +} + +BOOST_AUTO_TEST_CASE(cache_hash_get) +{ + auto test = [](auto _value0, auto _hash0, auto _value1, auto _hash1) -> void + { + typedef decltype(_hash0) Hash; + typedef decltype(_value0) Value; + static_assert( + std::is_same_v, "types of _hash0 and _hash1 need to be the same" + ); + static_assert( + std::is_same_v, + "types of _value0 and _value1 need to be the same" + ); + typename Cache::Ptr cache = std::make_shared>(); + Hash hash0 = cache->hash(_value0); + Hash hash1 = cache->hash(_value1); + BOOST_CHECK_EQUAL(hash0, _hash0); + BOOST_CHECK_EQUAL(hash1, _hash1); + BOOST_CHECK(cache->get(_hash0) == cache->end()); + BOOST_CHECK(cache->get(_hash1) == cache->end()); + cache->set(_value0); + BOOST_CHECK(cache->get(_hash0) != cache->end()); + BOOST_CHECK(*(cache->get(_hash0)->second) == _value0); + BOOST_CHECK(cache->get(hash1) == cache->end()); + cache->set(_value1); + BOOST_CHECK(cache->get(hash1) != cache->end()); + BOOST_CHECK(*(cache->get(hash1)->second) == _value1); + }; + test(0, static_cast(0), 1, static_cast(1)); + test(0.1f, static_cast(1036831949), 0.2f, static_cast(1045220557)); + test(0.1, static_cast(4591870180066957722), 0.2, static_cast(4596373779694328218)); + test( + "", + // different boost versions seem to return different hashes for strings, so we just calculate the correct hashes here. + Cache::hash(""), + "HELLO WORLD", + Cache::hash("HELLO WORLD") + ); + test( + std::string(), + // different boost versions seem to return different hashes for strings, so we just calculate the correct hashes here. + Cache::hash(std::string()), + std::string("HELLO WORLD"), + Cache::hash("HELLO WORLD") + ); + test( + Json{}, + // different boost versions seem to return different hashes for strings, so we just calculate the correct hashes here. + Cache::hash(Json{}), + Json{{"HELLO", "WORLD"}}, + Cache::hash(Json{{"HELLO", "WORLD"}}) + ); + test( + 0, + static_cast("044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d"), + 1, + static_cast("c89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6") + ); + test( + 0.1f, + static_cast("8cd160c72d102a6747abd189ac21d4a1f802e3fcc1bb8fc78cc4d558df0c7c21"), + 0.2f, + static_cast("c1907d585d0b0e66920f6383717e2e9e7c44e42ba86ef49b0e19983ffd702288") + ); + test( + 0.1, + static_cast("8cd160c72d102a6747abd189ac21d4a1f802e3fcc1bb8fc78cc4d558df0c7c21"), + 0.2, + static_cast("c1907d585d0b0e66920f6383717e2e9e7c44e42ba86ef49b0e19983ffd702288") + ); + test( + "", + static_cast("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"), + "HELLO WORLD", + static_cast("6c1223964c4674e3797678a0af4dee8b46a8ac1471d97cf37c136ce0937fa0df") + ); + test( + Json{}, + static_cast("efbde2c3aee204a69b7696d4b10ff31137fe78e3946306284f806e2dfc68b805"), + Json{{"HELLO", "WORLD"}}, + static_cast("90e22a3e1e4d820d1a76c04d130c08dd1cabb2c1d22ad7d582a0b5415d797bde") + ); +} + +BOOST_AUTO_TEST_SUITE_END() + +} diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index 9b8ce42921b6..5636047dc3c7 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -54,7 +54,7 @@ namespace solidity::yul::test namespace { -std::shared_ptr parse(std::string const& _source, Dialect const& _dialect, ErrorReporter& errorReporter) +std::shared_ptr parse(std::string const& _source, Dialect const& _dialect, ErrorReporter& errorReporter, Parser::DebugAttributeCache::Ptr debugAttributesCache = {}) { auto stream = CharStream(_source, ""); std::map> indicesToSourceNames; @@ -64,7 +64,8 @@ std::shared_ptr parse(std::string const& _source, Dialect const& _dialect, auto parserResult = yul::Parser( errorReporter, _dialect, - std::move(indicesToSourceNames) + std::move(indicesToSourceNames), + std::move(debugAttributesCache) ).parse(stream); if (parserResult) { @@ -998,6 +999,67 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_multiple_src_tags_on_one_line) CHECK_LOCATION(varX.debugData->originLocation, "source1", 4, 5); } +BOOST_AUTO_TEST_CASE(ethdebug_debug_attributes_empty) +{ + Parser::DebugAttributeCache::Ptr cache = std::make_shared(); + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = R"( + {} + )"; + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + std::shared_ptr result = parse(sourceText, dialect, reporter, cache); + BOOST_REQUIRE(cache->cache().size() == 0); +} + +BOOST_AUTO_TEST_CASE(ethdebug_debug_attributes_set_empty) +{ + Parser::DebugAttributeCache::Ptr cache = std::make_shared(); + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = R"( + /// @debug.set {} + {} + )"; + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + std::shared_ptr result = parse(sourceText, dialect, reporter, cache); + BOOST_REQUIRE(cache->cache().size() == 1); +} + + +BOOST_AUTO_TEST_CASE(ethdebug_debug_attributes_set) +{ + Parser::DebugAttributeCache::Ptr cache = std::make_shared(); + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = R"( + /// @debug.set {"hello": "world"} + {} + )"; + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + std::shared_ptr result = parse(sourceText, dialect, reporter, cache); + BOOST_REQUIRE(cache->cache().size() == 1); +} + +BOOST_AUTO_TEST_CASE(ethdebug_debug_attributes_multiple_set) +{ + Parser::DebugAttributeCache::Ptr cache = std::make_shared(); + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = R"( + /// @debug.set {"hello": "world"} + { + /// @debug.set {"hello": "world!"} + {} + /// @debug.set {"hello": "world"} + {} + } + )"; + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + std::shared_ptr result = parse(sourceText, dialect, reporter, cache); + BOOST_REQUIRE(cache->cache().size() == 2); +} + BOOST_AUTO_TEST_SUITE_END() } // end namespaces diff --git a/test/libyul/yulSyntaxTests/invalid/invalid_debug_merge.yul b/test/libyul/yulSyntaxTests/invalid/invalid_debug_merge.yul new file mode 100644 index 000000000000..13200b008cb8 --- /dev/null +++ b/test/libyul/yulSyntaxTests/invalid/invalid_debug_merge.yul @@ -0,0 +1,7 @@ +object "object" { + code { + /// @debug.merge {"HELLO": 2 + } +} +// ---- +// SyntaxError 5721: (37-65): @debug.merge: Could not parse debug data: parse error at line 1, column 12: syntax error while parsing object - unexpected end of input; expected '}' diff --git a/test/libyul/yulSyntaxTests/invalid/invalid_debug_patch.yul b/test/libyul/yulSyntaxTests/invalid/invalid_debug_patch.yul new file mode 100644 index 000000000000..3f1d15e962da --- /dev/null +++ b/test/libyul/yulSyntaxTests/invalid/invalid_debug_patch.yul @@ -0,0 +1,7 @@ +object "object" { + code { + /// @debug.patch {"HELLO": invalid + } +} +// ---- +// SyntaxError 5721: (37-71): @debug.patch: Could not parse debug data: parse error at line 1, column 11: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal diff --git a/test/libyul/yulSyntaxTests/invalid/invalid_debug_patch_patch_object.yul b/test/libyul/yulSyntaxTests/invalid/invalid_debug_patch_patch_object.yul new file mode 100644 index 000000000000..a5c02823f27c --- /dev/null +++ b/test/libyul/yulSyntaxTests/invalid/invalid_debug_patch_patch_object.yul @@ -0,0 +1,7 @@ +object "object" { + code { + /// @debug.patch { "op": "unknown_operation", "path": "/variable_a", "value": ["test"] } + } +} +// ---- +// SyntaxError 9426: (37-125): @debug.patch: Could not patch debug data: parse error: operation value 'unknown_operation' is invalid diff --git a/test/libyul/yulSyntaxTests/invalid/invalid_debug_set.yul b/test/libyul/yulSyntaxTests/invalid/invalid_debug_set.yul new file mode 100644 index 000000000000..3c99b7cb52bd --- /dev/null +++ b/test/libyul/yulSyntaxTests/invalid/invalid_debug_set.yul @@ -0,0 +1,7 @@ +object "object" { + code { + /// @debug.set {"HELLO": "WORLD + } +} +// ---- +// SyntaxError 5721: (37-68): @debug.set: Could not parse debug data: parse error at line 1, column 17: syntax error while parsing value - invalid string: missing closing quote; last read: '"WORLD'