mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-17 12:34:35 +03:00
Added NodeList to abstract double linked list of nodes
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user