From 917f19d940935998aa9dfa7479368834451622f7 Mon Sep 17 00:00:00 2001 From: kobalicek Date: Thu, 14 Sep 2023 17:00:28 +0200 Subject: [PATCH] Added NodeList to abstract double linked list of nodes --- src/asmjit/core/builder.cpp | 45 ++++++++++++------------ src/asmjit/core/builder.h | 68 +++++++++++++++++++++++++++++++++---- 2 files changed, 82 insertions(+), 31 deletions(-) diff --git a/src/asmjit/core/builder.cpp b/src/asmjit/core/builder.cpp index dcf7b4f..9ec29b9 100644 --- a/src/asmjit/core/builder.cpp +++ b/src/asmjit/core/builder.cpp @@ -151,14 +151,13 @@ BaseNode* BaseBuilder::addNode(BaseNode* node) noexcept { ASMJIT_ASSERT(!node->isActive()); if (!_cursor) { - if (!_firstNode) { - _firstNode = node; - _lastNode = node; + if (_nodeList.empty()) { + _nodeList.reset(node, node); } else { - node->_next = _firstNode; - _firstNode->_prev = node; - _firstNode = node; + node->_next = _nodeList.first(); + _nodeList._first->_prev = node; + _nodeList._first = node; } } else { @@ -172,7 +171,7 @@ BaseNode* BaseBuilder::addNode(BaseNode* node) noexcept { if (next) next->_prev = node; else - _lastNode = node; + _nodeList._last = node; } node->addFlags(NodeFlags::kIsActive); @@ -201,7 +200,7 @@ BaseNode* BaseBuilder::addAfter(BaseNode* node, BaseNode* ref) noexcept { if (next) next->_prev = node; else - _lastNode = node; + _nodeList._last = node; return node; } @@ -226,7 +225,7 @@ BaseNode* BaseBuilder::addBefore(BaseNode* node, BaseNode* ref) noexcept { if (prev) prev->_next = node; else - _firstNode = node; + _nodeList._first = node; return node; } @@ -238,13 +237,13 @@ BaseNode* BaseBuilder::removeNode(BaseNode* node) noexcept { BaseNode* prev = node->prev(); BaseNode* next = node->next(); - if (_firstNode == node) - _firstNode = next; + if (_nodeList._first == node) + _nodeList._first = next; else prev->_next = next; - if (_lastNode == node) - _lastNode = prev; + if (_nodeList._last == node) + _nodeList._last = prev; else next->_prev = prev; @@ -272,13 +271,13 @@ void BaseBuilder::removeNodes(BaseNode* first, BaseNode* last) noexcept { BaseNode* prev = first->prev(); BaseNode* next = last->next(); - if (_firstNode == first) - _firstNode = next; + if (_nodeList._first == first) + _nodeList._first = next; else prev->_next = next; - if (_lastNode == last) - _lastNode = prev; + if (_nodeList._last == last) + _nodeList._last = prev; else next->_prev = prev; @@ -368,7 +367,7 @@ Error BaseBuilder::section(Section* section) { if (node->_nextSection) _cursor = node->_nextSection->_prev; else - _cursor = _lastNode; + _cursor = _nodeList.last(); } return kErrorOk; @@ -378,7 +377,7 @@ void BaseBuilder::updateSectionLinks() noexcept { if (!_dirtySectionLinks) return; - BaseNode* node_ = _firstNode; + BaseNode* node_ = _nodeList.first(); SectionNode* currentSection = nullptr; while (node_) { @@ -758,7 +757,7 @@ Error BaseBuilder::comment(const char* data, size_t size) { Error BaseBuilder::serializeTo(BaseEmitter* dst) { Error err = kErrorOk; - BaseNode* node_ = _firstNode; + BaseNode* node_ = _nodeList.first(); Operand_ opArray[Globals::kMaxOpCount]; @@ -854,8 +853,7 @@ Error BaseBuilder::onAttach(CodeHolder* code) noexcept { ASMJIT_ASSUME(initialSection != nullptr); _cursor = initialSection; - _firstNode = initialSection; - _lastNode = initialSection; + _nodeList.reset(initialSection, initialSection); initialSection->setFlags(NodeFlags::kIsActive); return kErrorOk; @@ -873,8 +871,7 @@ Error BaseBuilder::onDetach(CodeHolder* code) noexcept { _nodeFlags = NodeFlags::kNone; _cursor = nullptr; - _firstNode = nullptr; - _lastNode = nullptr; + _nodeList.reset(); return Base::onDetach(code); } diff --git a/src/asmjit/core/builder.h b/src/asmjit/core/builder.h index cfca7cc..2ff035b 100644 --- a/src/asmjit/core/builder.h +++ b/src/asmjit/core/builder.h @@ -109,7 +109,7 @@ enum class NodeFlags : uint8_t { }; ASMJIT_DEFINE_ENUM_FLAGS(NodeFlags) -//! Type of the sentinel (purery informative purpose). +//! Type of the sentinel (purely informative purpose). enum class SentinelType : uint8_t { //! Type of the sentinel is not known. kUnknown = 0u, @@ -117,6 +117,60 @@ enum class SentinelType : uint8_t { kFuncEnd = 1u }; +//! Node list. +//! +//! A double-linked list of pointers to \ref BaseNode, managed by \ref BaseBuilder or \ref BaseCompiler. +//! +//! \note At the moment NodeList is just a view, but it's planned that it will get more functionality in the future. +class NodeList { +public: + //! \name Members + //! \{ + + //! First node in the list or nullptr if there are no nodes in the list. + BaseNode* _first = nullptr; + //! Last node in the list or nullptr if there are no nodes in the list. + BaseNode* _last = nullptr; + + //! \} + + //! \name Construction & Destruction + //! \{ + + ASMJIT_INLINE_NODEBUG NodeList() noexcept {} + + ASMJIT_INLINE_NODEBUG NodeList(BaseNode* first, BaseNode* last) noexcept + : _first(first), + _last(last) {} + + //! \} + + //! \name Reset + //! \{ + + ASMJIT_INLINE_NODEBUG void reset() noexcept { + _first = nullptr; + _last = nullptr; + } + + ASMJIT_INLINE_NODEBUG void reset(BaseNode* first, BaseNode* last) noexcept { + _first = first; + _last = last; + } + + //! \} + + //! \name Accessors + //! \{ + + ASMJIT_INLINE_NODEBUG bool empty() const noexcept { return _first == nullptr; } + + ASMJIT_INLINE_NODEBUG BaseNode* first() const noexcept { return _first; } + ASMJIT_INLINE_NODEBUG BaseNode* last() const noexcept { return _last; } + + //! \} +}; + //! Builder interface. //! //! `BaseBuilder` interface was designed to be used as a \ref BaseAssembler replacement in case pre-processing or @@ -153,10 +207,8 @@ public: //! Current node (cursor). BaseNode* _cursor = nullptr; - //! First node of the current section. - BaseNode* _firstNode = nullptr; - //! Last node of the current section. - BaseNode* _lastNode = nullptr; + //! First and last nodes. + NodeList _nodeList; //! Flags assigned to each new node. NodeFlags _nodeFlags = NodeFlags::kNone; @@ -178,10 +230,12 @@ public: //! \name Node Management //! \{ + ASMJIT_INLINE_NODEBUG NodeList nodeList() const noexcept { return _nodeList; } + //! Returns the first node. - ASMJIT_INLINE_NODEBUG BaseNode* firstNode() const noexcept { return _firstNode; } + ASMJIT_INLINE_NODEBUG BaseNode* firstNode() const noexcept { return _nodeList.first(); } //! Returns the last node. - ASMJIT_INLINE_NODEBUG BaseNode* lastNode() const noexcept { return _lastNode; } + ASMJIT_INLINE_NODEBUG BaseNode* lastNode() const noexcept { return _nodeList.last(); } //! Allocates and instantiates a new node of type `T` and returns its instance. If the allocation fails `nullptr` //! is returned.