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());
|
ASMJIT_ASSERT(!node->isActive());
|
||||||
|
|
||||||
if (!_cursor) {
|
if (!_cursor) {
|
||||||
if (!_firstNode) {
|
if (_nodeList.empty()) {
|
||||||
_firstNode = node;
|
_nodeList.reset(node, node);
|
||||||
_lastNode = node;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
node->_next = _firstNode;
|
node->_next = _nodeList.first();
|
||||||
_firstNode->_prev = node;
|
_nodeList._first->_prev = node;
|
||||||
_firstNode = node;
|
_nodeList._first = node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -172,7 +171,7 @@ BaseNode* BaseBuilder::addNode(BaseNode* node) noexcept {
|
|||||||
if (next)
|
if (next)
|
||||||
next->_prev = node;
|
next->_prev = node;
|
||||||
else
|
else
|
||||||
_lastNode = node;
|
_nodeList._last = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
node->addFlags(NodeFlags::kIsActive);
|
node->addFlags(NodeFlags::kIsActive);
|
||||||
@@ -201,7 +200,7 @@ BaseNode* BaseBuilder::addAfter(BaseNode* node, BaseNode* ref) noexcept {
|
|||||||
if (next)
|
if (next)
|
||||||
next->_prev = node;
|
next->_prev = node;
|
||||||
else
|
else
|
||||||
_lastNode = node;
|
_nodeList._last = node;
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@@ -226,7 +225,7 @@ BaseNode* BaseBuilder::addBefore(BaseNode* node, BaseNode* ref) noexcept {
|
|||||||
if (prev)
|
if (prev)
|
||||||
prev->_next = node;
|
prev->_next = node;
|
||||||
else
|
else
|
||||||
_firstNode = node;
|
_nodeList._first = node;
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@@ -238,13 +237,13 @@ BaseNode* BaseBuilder::removeNode(BaseNode* node) noexcept {
|
|||||||
BaseNode* prev = node->prev();
|
BaseNode* prev = node->prev();
|
||||||
BaseNode* next = node->next();
|
BaseNode* next = node->next();
|
||||||
|
|
||||||
if (_firstNode == node)
|
if (_nodeList._first == node)
|
||||||
_firstNode = next;
|
_nodeList._first = next;
|
||||||
else
|
else
|
||||||
prev->_next = next;
|
prev->_next = next;
|
||||||
|
|
||||||
if (_lastNode == node)
|
if (_nodeList._last == node)
|
||||||
_lastNode = prev;
|
_nodeList._last = prev;
|
||||||
else
|
else
|
||||||
next->_prev = prev;
|
next->_prev = prev;
|
||||||
|
|
||||||
@@ -272,13 +271,13 @@ void BaseBuilder::removeNodes(BaseNode* first, BaseNode* last) noexcept {
|
|||||||
BaseNode* prev = first->prev();
|
BaseNode* prev = first->prev();
|
||||||
BaseNode* next = last->next();
|
BaseNode* next = last->next();
|
||||||
|
|
||||||
if (_firstNode == first)
|
if (_nodeList._first == first)
|
||||||
_firstNode = next;
|
_nodeList._first = next;
|
||||||
else
|
else
|
||||||
prev->_next = next;
|
prev->_next = next;
|
||||||
|
|
||||||
if (_lastNode == last)
|
if (_nodeList._last == last)
|
||||||
_lastNode = prev;
|
_nodeList._last = prev;
|
||||||
else
|
else
|
||||||
next->_prev = prev;
|
next->_prev = prev;
|
||||||
|
|
||||||
@@ -368,7 +367,7 @@ Error BaseBuilder::section(Section* section) {
|
|||||||
if (node->_nextSection)
|
if (node->_nextSection)
|
||||||
_cursor = node->_nextSection->_prev;
|
_cursor = node->_nextSection->_prev;
|
||||||
else
|
else
|
||||||
_cursor = _lastNode;
|
_cursor = _nodeList.last();
|
||||||
}
|
}
|
||||||
|
|
||||||
return kErrorOk;
|
return kErrorOk;
|
||||||
@@ -378,7 +377,7 @@ void BaseBuilder::updateSectionLinks() noexcept {
|
|||||||
if (!_dirtySectionLinks)
|
if (!_dirtySectionLinks)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BaseNode* node_ = _firstNode;
|
BaseNode* node_ = _nodeList.first();
|
||||||
SectionNode* currentSection = nullptr;
|
SectionNode* currentSection = nullptr;
|
||||||
|
|
||||||
while (node_) {
|
while (node_) {
|
||||||
@@ -758,7 +757,7 @@ Error BaseBuilder::comment(const char* data, size_t size) {
|
|||||||
|
|
||||||
Error BaseBuilder::serializeTo(BaseEmitter* dst) {
|
Error BaseBuilder::serializeTo(BaseEmitter* dst) {
|
||||||
Error err = kErrorOk;
|
Error err = kErrorOk;
|
||||||
BaseNode* node_ = _firstNode;
|
BaseNode* node_ = _nodeList.first();
|
||||||
|
|
||||||
Operand_ opArray[Globals::kMaxOpCount];
|
Operand_ opArray[Globals::kMaxOpCount];
|
||||||
|
|
||||||
@@ -854,8 +853,7 @@ Error BaseBuilder::onAttach(CodeHolder* code) noexcept {
|
|||||||
|
|
||||||
ASMJIT_ASSUME(initialSection != nullptr);
|
ASMJIT_ASSUME(initialSection != nullptr);
|
||||||
_cursor = initialSection;
|
_cursor = initialSection;
|
||||||
_firstNode = initialSection;
|
_nodeList.reset(initialSection, initialSection);
|
||||||
_lastNode = initialSection;
|
|
||||||
initialSection->setFlags(NodeFlags::kIsActive);
|
initialSection->setFlags(NodeFlags::kIsActive);
|
||||||
|
|
||||||
return kErrorOk;
|
return kErrorOk;
|
||||||
@@ -873,8 +871,7 @@ Error BaseBuilder::onDetach(CodeHolder* code) noexcept {
|
|||||||
|
|
||||||
_nodeFlags = NodeFlags::kNone;
|
_nodeFlags = NodeFlags::kNone;
|
||||||
_cursor = nullptr;
|
_cursor = nullptr;
|
||||||
_firstNode = nullptr;
|
_nodeList.reset();
|
||||||
_lastNode = nullptr;
|
|
||||||
|
|
||||||
return Base::onDetach(code);
|
return Base::onDetach(code);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ enum class NodeFlags : uint8_t {
|
|||||||
};
|
};
|
||||||
ASMJIT_DEFINE_ENUM_FLAGS(NodeFlags)
|
ASMJIT_DEFINE_ENUM_FLAGS(NodeFlags)
|
||||||
|
|
||||||
//! Type of the sentinel (purery informative purpose).
|
//! Type of the sentinel (purely informative purpose).
|
||||||
enum class SentinelType : uint8_t {
|
enum class SentinelType : uint8_t {
|
||||||
//! Type of the sentinel is not known.
|
//! Type of the sentinel is not known.
|
||||||
kUnknown = 0u,
|
kUnknown = 0u,
|
||||||
@@ -117,6 +117,60 @@ enum class SentinelType : uint8_t {
|
|||||||
kFuncEnd = 1u
|
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.
|
//! Builder interface.
|
||||||
//!
|
//!
|
||||||
//! `BaseBuilder` interface was designed to be used as a \ref BaseAssembler replacement in case pre-processing or
|
//! `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).
|
//! Current node (cursor).
|
||||||
BaseNode* _cursor = nullptr;
|
BaseNode* _cursor = nullptr;
|
||||||
//! First node of the current section.
|
//! First and last nodes.
|
||||||
BaseNode* _firstNode = nullptr;
|
NodeList _nodeList;
|
||||||
//! Last node of the current section.
|
|
||||||
BaseNode* _lastNode = nullptr;
|
|
||||||
|
|
||||||
//! Flags assigned to each new node.
|
//! Flags assigned to each new node.
|
||||||
NodeFlags _nodeFlags = NodeFlags::kNone;
|
NodeFlags _nodeFlags = NodeFlags::kNone;
|
||||||
@@ -178,10 +230,12 @@ public:
|
|||||||
//! \name Node Management
|
//! \name Node Management
|
||||||
//! \{
|
//! \{
|
||||||
|
|
||||||
|
ASMJIT_INLINE_NODEBUG NodeList nodeList() const noexcept { return _nodeList; }
|
||||||
|
|
||||||
//! Returns the first node.
|
//! 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.
|
//! 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`
|
//! Allocates and instantiates a new node of type `T` and returns its instance. If the allocation fails `nullptr`
|
||||||
//! is returned.
|
//! is returned.
|
||||||
|
|||||||
Reference in New Issue
Block a user