Added NodeList to abstract double linked list of nodes

This commit is contained in:
kobalicek
2023-09-14 17:00:28 +02:00
parent 87bec89b10
commit 917f19d940
2 changed files with 82 additions and 31 deletions

View File

@@ -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);
}

View File

@@ -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.