aboutsummaryrefslogtreecommitdiff
path: root/client/asmjit/core/builder.cpp
diff options
context:
space:
mode:
authorauth12 <[email protected]>2020-07-21 13:07:42 -0700
committerauth12 <[email protected]>2020-07-21 13:07:42 -0700
commitf09669dd5846d95b063712571ccb7519910a0d6e (patch)
tree902f5ad201651f2d96ccf619e90b76cfa06a7b9b /client/asmjit/core/builder.cpp
parentSyscalls. (diff)
downloadloader-f09669dd5846d95b063712571ccb7519910a0d6e.tar.xz
loader-f09669dd5846d95b063712571ccb7519910a0d6e.zip
Added game selection.
Started process wrapper. Removed asmjit.
Diffstat (limited to 'client/asmjit/core/builder.cpp')
-rw-r--r--client/asmjit/core/builder.cpp927
1 files changed, 0 insertions, 927 deletions
diff --git a/client/asmjit/core/builder.cpp b/client/asmjit/core/builder.cpp
deleted file mode 100644
index a582e96..0000000
--- a/client/asmjit/core/builder.cpp
+++ /dev/null
@@ -1,927 +0,0 @@
-// AsmJit - Machine code generation for C++
-//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
-
-#include "../core/api-build_p.h"
-#ifndef ASMJIT_NO_BUILDER
-
-#include "../core/builder.h"
-#include "../core/emitterutils_p.h"
-#include "../core/errorhandler.h"
-#include "../core/formatter.h"
-#include "../core/logger.h"
-#include "../core/support.h"
-
-ASMJIT_BEGIN_NAMESPACE
-
-// ============================================================================
-// [asmjit::PostponedErrorHandler (Internal)]
-// ============================================================================
-
-//! Postponed error handler that never throws. Used as a temporal error handler
-//! to run passes. If error occurs, the caller is notified and will call the
-//! real error handler, that can throw.
-class PostponedErrorHandler : public ErrorHandler {
-public:
- void handleError(Error err, const char* message, BaseEmitter* origin) override {
- DebugUtils::unused(err, origin);
- _message.assign(message);
- }
-
- StringTmp<128> _message;
-};
-
-// ============================================================================
-// [asmjit::BaseBuilder - Utilities]
-// ============================================================================
-
-static void BaseBuilder_deletePasses(BaseBuilder* self) noexcept {
- for (Pass* pass : self->_passes)
- pass->~Pass();
- self->_passes.reset();
-}
-
-// ============================================================================
-// [asmjit::BaseBuilder - Construction / Destruction]
-// ============================================================================
-
-BaseBuilder::BaseBuilder() noexcept
- : BaseEmitter(kTypeBuilder),
- _codeZone(32768 - Zone::kBlockOverhead),
- _dataZone(16384 - Zone::kBlockOverhead),
- _passZone(65536 - Zone::kBlockOverhead),
- _allocator(&_codeZone),
- _passes(),
- _labelNodes(),
- _cursor(nullptr),
- _firstNode(nullptr),
- _lastNode(nullptr),
- _nodeFlags(0) {}
-
-BaseBuilder::~BaseBuilder() noexcept {
- BaseBuilder_deletePasses(this);
-}
-
-// ============================================================================
-// [asmjit::BaseBuilder - Node Management]
-// ============================================================================
-
-Error BaseBuilder::_newInstNode(InstNode** out, uint32_t instId, uint32_t instOptions, uint32_t opCount) {
- uint32_t opCapacity = InstNode::capacityOfOpCount(opCount);
- ASMJIT_ASSERT(opCapacity >= InstNode::kBaseOpCapacity);
-
- InstNode* node = _allocator.allocT<InstNode>(InstNode::nodeSizeOfOpCapacity(opCapacity));
- if (ASMJIT_UNLIKELY(!node))
- return reportError(DebugUtils::errored(kErrorOutOfMemory));
-
- *out = new(node) InstNode(this, instId, instOptions, opCount, opCapacity);
- return kErrorOk;
-}
-
-
-Error BaseBuilder::_newLabelNode(LabelNode** out) {
- *out = nullptr;
-
- ASMJIT_PROPAGATE(_newNodeT<LabelNode>(out));
- return registerLabelNode(*out);
-}
-
-Error BaseBuilder::_newAlignNode(AlignNode** out, uint32_t alignMode, uint32_t alignment) {
- *out = nullptr;
- return _newNodeT<AlignNode>(out, alignMode, alignment);
-}
-
-Error BaseBuilder::_newEmbedDataNode(EmbedDataNode** out, uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount) {
- *out = nullptr;
-
- uint32_t deabstractDelta = Type::deabstractDeltaOfSize(registerSize());
- uint32_t finalTypeId = Type::deabstract(typeId, deabstractDelta);
-
- if (ASMJIT_UNLIKELY(!Type::isValid(finalTypeId)))
- return reportError(DebugUtils::errored(kErrorInvalidArgument));
-
- uint32_t typeSize = Type::sizeOf(finalTypeId);
- Support::FastUInt8 of = 0;
-
- size_t dataSize = Support::mulOverflow(itemCount, size_t(typeSize), &of);
- if (ASMJIT_UNLIKELY(of))
- return reportError(DebugUtils::errored(kErrorOutOfMemory));
-
- EmbedDataNode* node;
- ASMJIT_PROPAGATE(_newNodeT<EmbedDataNode>(&node));
-
- node->_embed._typeId = uint8_t(typeId);
- node->_embed._typeSize = uint8_t(typeSize);
- node->_itemCount = itemCount;
- node->_repeatCount = repeatCount;
-
- uint8_t* dstData = node->_inlineData;
- if (dataSize > EmbedDataNode::kInlineBufferSize) {
- dstData = static_cast<uint8_t*>(_dataZone.alloc(dataSize, 8));
- if (ASMJIT_UNLIKELY(!dstData))
- return reportError(DebugUtils::errored(kErrorOutOfMemory));
- node->_externalData = dstData;
- }
-
- if (data)
- memcpy(dstData, data, dataSize);
-
- *out = node;
- return kErrorOk;
-}
-
-Error BaseBuilder::_newConstPoolNode(ConstPoolNode** out) {
- *out = nullptr;
-
- ASMJIT_PROPAGATE(_newNodeT<ConstPoolNode>(out));
- return registerLabelNode(*out);
-}
-
-Error BaseBuilder::_newCommentNode(CommentNode** out, const char* data, size_t size) {
- *out = nullptr;
-
- if (data) {
- if (size == SIZE_MAX)
- size = strlen(data);
-
- if (size > 0) {
- data = static_cast<char*>(_dataZone.dup(data, size, true));
- if (ASMJIT_UNLIKELY(!data))
- return reportError(DebugUtils::errored(kErrorOutOfMemory));
- }
- }
-
- return _newNodeT<CommentNode>(out, data);
-}
-
-BaseNode* BaseBuilder::addNode(BaseNode* node) noexcept {
- ASMJIT_ASSERT(node);
- ASMJIT_ASSERT(!node->_prev);
- ASMJIT_ASSERT(!node->_next);
- ASMJIT_ASSERT(!node->isActive());
-
- if (!_cursor) {
- if (!_firstNode) {
- _firstNode = node;
- _lastNode = node;
- }
- else {
- node->_next = _firstNode;
- _firstNode->_prev = node;
- _firstNode = node;
- }
- }
- else {
- BaseNode* prev = _cursor;
- BaseNode* next = _cursor->next();
-
- node->_prev = prev;
- node->_next = next;
-
- prev->_next = node;
- if (next)
- next->_prev = node;
- else
- _lastNode = node;
- }
-
- node->addFlags(BaseNode::kFlagIsActive);
- if (node->isSection())
- _dirtySectionLinks = true;
-
- _cursor = node;
- return node;
-}
-
-BaseNode* BaseBuilder::addAfter(BaseNode* node, BaseNode* ref) noexcept {
- ASMJIT_ASSERT(node);
- ASMJIT_ASSERT(ref);
-
- ASMJIT_ASSERT(!node->_prev);
- ASMJIT_ASSERT(!node->_next);
-
- BaseNode* prev = ref;
- BaseNode* next = ref->next();
-
- node->_prev = prev;
- node->_next = next;
-
- node->addFlags(BaseNode::kFlagIsActive);
- if (node->isSection())
- _dirtySectionLinks = true;
-
- prev->_next = node;
- if (next)
- next->_prev = node;
- else
- _lastNode = node;
-
- return node;
-}
-
-BaseNode* BaseBuilder::addBefore(BaseNode* node, BaseNode* ref) noexcept {
- ASMJIT_ASSERT(node != nullptr);
- ASMJIT_ASSERT(!node->_prev);
- ASMJIT_ASSERT(!node->_next);
- ASMJIT_ASSERT(!node->isActive());
- ASMJIT_ASSERT(ref != nullptr);
- ASMJIT_ASSERT(ref->isActive());
-
- BaseNode* prev = ref->prev();
- BaseNode* next = ref;
-
- node->_prev = prev;
- node->_next = next;
-
- node->addFlags(BaseNode::kFlagIsActive);
- if (node->isSection())
- _dirtySectionLinks = true;
-
- next->_prev = node;
- if (prev)
- prev->_next = node;
- else
- _firstNode = node;
-
- return node;
-}
-
-BaseNode* BaseBuilder::removeNode(BaseNode* node) noexcept {
- if (!node->isActive())
- return node;
-
- BaseNode* prev = node->prev();
- BaseNode* next = node->next();
-
- if (_firstNode == node)
- _firstNode = next;
- else
- prev->_next = next;
-
- if (_lastNode == node)
- _lastNode = prev;
- else
- next->_prev = prev;
-
- node->_prev = nullptr;
- node->_next = nullptr;
- node->clearFlags(BaseNode::kFlagIsActive);
- if (node->isSection())
- _dirtySectionLinks = true;
-
- if (_cursor == node)
- _cursor = prev;
-
- return node;
-}
-
-void BaseBuilder::removeNodes(BaseNode* first, BaseNode* last) noexcept {
- if (first == last) {
- removeNode(first);
- return;
- }
-
- if (!first->isActive())
- return;
-
- BaseNode* prev = first->prev();
- BaseNode* next = last->next();
-
- if (_firstNode == first)
- _firstNode = next;
- else
- prev->_next = next;
-
- if (_lastNode == last)
- _lastNode = prev;
- else
- next->_prev = prev;
-
- BaseNode* node = first;
- uint32_t didRemoveSection = false;
-
- for (;;) {
- next = node->next();
- ASMJIT_ASSERT(next != nullptr);
-
- node->_prev = nullptr;
- node->_next = nullptr;
- node->clearFlags(BaseNode::kFlagIsActive);
- didRemoveSection |= uint32_t(node->isSection());
-
- if (_cursor == node)
- _cursor = prev;
-
- if (node == last)
- break;
- node = next;
- }
-
- if (didRemoveSection)
- _dirtySectionLinks = true;
-}
-
-BaseNode* BaseBuilder::setCursor(BaseNode* node) noexcept {
- BaseNode* old = _cursor;
- _cursor = node;
- return old;
-}
-
-// ============================================================================
-// [asmjit::BaseBuilder - Section]
-// ============================================================================
-
-Error BaseBuilder::sectionNodeOf(SectionNode** out, uint32_t sectionId) {
- *out = nullptr;
-
- if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
-
- if (ASMJIT_UNLIKELY(!_code->isSectionValid(sectionId)))
- return reportError(DebugUtils::errored(kErrorInvalidSection));
-
- if (sectionId >= _sectionNodes.size()) {
- Error err = _sectionNodes.reserve(&_allocator, sectionId + 1);
- if (ASMJIT_UNLIKELY(err != kErrorOk))
- return reportError(err);
- }
-
- SectionNode* node = nullptr;
- if (sectionId < _sectionNodes.size())
- node = _sectionNodes[sectionId];
-
- if (!node) {
- ASMJIT_PROPAGATE(_newNodeT<SectionNode>(&node, sectionId));
-
- // We have already reserved enough space, this cannot fail now.
- if (sectionId >= _sectionNodes.size())
- _sectionNodes.resize(&_allocator, sectionId + 1);
-
- _sectionNodes[sectionId] = node;
- }
-
- *out = node;
- return kErrorOk;
-}
-
-Error BaseBuilder::section(Section* section) {
- SectionNode* node;
- ASMJIT_PROPAGATE(sectionNodeOf(&node, section->id()));
-
- if (!node->isActive()) {
- // Insert the section at the end if it was not part of the code.
- addAfter(node, lastNode());
- _cursor = node;
- }
- else {
- // This is a bit tricky. We cache section links to make sure that
- // switching sections doesn't involve traversal in linked-list unless
- // the position of the section has changed.
- if (hasDirtySectionLinks())
- updateSectionLinks();
-
- if (node->_nextSection)
- _cursor = node->_nextSection->_prev;
- else
- _cursor = _lastNode;
- }
-
- return kErrorOk;
-}
-
-void BaseBuilder::updateSectionLinks() noexcept {
- if (!_dirtySectionLinks)
- return;
-
- BaseNode* node_ = _firstNode;
- SectionNode* currentSection = nullptr;
-
- while (node_) {
- if (node_->isSection()) {
- if (currentSection)
- currentSection->_nextSection = node_->as<SectionNode>();
- currentSection = node_->as<SectionNode>();
- }
- node_ = node_->next();
- }
-
- if (currentSection)
- currentSection->_nextSection = nullptr;
-
- _dirtySectionLinks = false;
-}
-
-// ============================================================================
-// [asmjit::BaseBuilder - Labels]
-// ============================================================================
-
-Error BaseBuilder::labelNodeOf(LabelNode** out, uint32_t labelId) {
- *out = nullptr;
-
- if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
-
- uint32_t index = labelId;
- if (ASMJIT_UNLIKELY(index >= _code->labelCount()))
- return DebugUtils::errored(kErrorInvalidLabel);
-
- if (index >= _labelNodes.size())
- ASMJIT_PROPAGATE(_labelNodes.resize(&_allocator, index + 1));
-
- LabelNode* node = _labelNodes[index];
- if (!node) {
- ASMJIT_PROPAGATE(_newNodeT<LabelNode>(&node, labelId));
- _labelNodes[index] = node;
- }
-
- *out = node;
- return kErrorOk;
-}
-
-Error BaseBuilder::registerLabelNode(LabelNode* node) {
- if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
-
- LabelEntry* le;
- ASMJIT_PROPAGATE(_code->newLabelEntry(&le));
- uint32_t labelId = le->id();
-
- // We just added one label so it must be true.
- ASMJIT_ASSERT(_labelNodes.size() < labelId + 1);
- ASMJIT_PROPAGATE(_labelNodes.resize(&_allocator, labelId + 1));
-
- _labelNodes[labelId] = node;
- node->_labelId = labelId;
-
- return kErrorOk;
-}
-
-static Error BaseBuilder_newLabelInternal(BaseBuilder* self, uint32_t labelId) {
- ASMJIT_ASSERT(self->_labelNodes.size() < labelId + 1);
-
- uint32_t growBy = labelId - self->_labelNodes.size();
- Error err = self->_labelNodes.willGrow(&self->_allocator, growBy);
-
- if (ASMJIT_UNLIKELY(err))
- return self->reportError(err);
-
- LabelNode* node;
- ASMJIT_PROPAGATE(self->_newNodeT<LabelNode>(&node, labelId));
-
- self->_labelNodes.resize(&self->_allocator, labelId + 1);
- self->_labelNodes[labelId] = node;
- node->_labelId = labelId;
- return kErrorOk;
-}
-
-Label BaseBuilder::newLabel() {
- uint32_t labelId = Globals::kInvalidId;
- LabelEntry* le;
-
- if (_code &&
- _code->newLabelEntry(&le) == kErrorOk &&
- BaseBuilder_newLabelInternal(this, le->id()) == kErrorOk) {
- labelId = le->id();
- }
-
- return Label(labelId);
-}
-
-Label BaseBuilder::newNamedLabel(const char* name, size_t nameSize, uint32_t type, uint32_t parentId) {
- uint32_t labelId = Globals::kInvalidId;
- LabelEntry* le;
-
- if (_code &&
- _code->newNamedLabelEntry(&le, name, nameSize, type, parentId) == kErrorOk &&
- BaseBuilder_newLabelInternal(this, le->id()) == kErrorOk) {
- labelId = le->id();
- }
-
- return Label(labelId);
-}
-
-Error BaseBuilder::bind(const Label& label) {
- LabelNode* node;
- ASMJIT_PROPAGATE(labelNodeOf(&node, label));
-
- addNode(node);
- return kErrorOk;
-}
-
-// ============================================================================
-// [asmjit::BaseBuilder - Passes]
-// ============================================================================
-
-ASMJIT_FAVOR_SIZE Pass* BaseBuilder::passByName(const char* name) const noexcept {
- for (Pass* pass : _passes)
- if (strcmp(pass->name(), name) == 0)
- return pass;
- return nullptr;
-}
-
-ASMJIT_FAVOR_SIZE Error BaseBuilder::addPass(Pass* pass) noexcept {
- if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
-
- if (ASMJIT_UNLIKELY(pass == nullptr)) {
- // Since this is directly called by `addPassT()` we treat `null` argument
- // as out-of-memory condition. Otherwise it would be API misuse.
- return DebugUtils::errored(kErrorOutOfMemory);
- }
- else if (ASMJIT_UNLIKELY(pass->_cb)) {
- // Kinda weird, but okay...
- if (pass->_cb == this)
- return kErrorOk;
- return DebugUtils::errored(kErrorInvalidState);
- }
-
- ASMJIT_PROPAGATE(_passes.append(&_allocator, pass));
- pass->_cb = this;
- return kErrorOk;
-}
-
-ASMJIT_FAVOR_SIZE Error BaseBuilder::deletePass(Pass* pass) noexcept {
- if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
-
- if (ASMJIT_UNLIKELY(pass == nullptr))
- return DebugUtils::errored(kErrorInvalidArgument);
-
- if (pass->_cb != nullptr) {
- if (pass->_cb != this)
- return DebugUtils::errored(kErrorInvalidState);
-
- uint32_t index = _passes.indexOf(pass);
- ASMJIT_ASSERT(index != Globals::kNotFound);
-
- pass->_cb = nullptr;
- _passes.removeAt(index);
- }
-
- pass->~Pass();
- return kErrorOk;
-}
-
-Error BaseBuilder::runPasses() {
- if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
-
- if (_passes.empty())
- return kErrorOk;
-
- ErrorHandler* prev = errorHandler();
- PostponedErrorHandler postponed;
-
- Error err = kErrorOk;
- setErrorHandler(&postponed);
-
- for (Pass* pass : _passes) {
- _passZone.reset();
- err = pass->run(&_passZone, _logger);
- if (err)
- break;
- }
- _passZone.reset();
- setErrorHandler(prev);
-
- if (ASMJIT_UNLIKELY(err))
- return reportError(err, !postponed._message.empty() ? postponed._message.data() : nullptr);
-
- return kErrorOk;
-}
-
-// ============================================================================
-// [asmjit::BaseBuilder - Emit]
-// ============================================================================
-
-Error BaseBuilder::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) {
- uint32_t opCount = EmitterUtils::opCountFromEmitArgs(o0, o1, o2, opExt);
- uint32_t options = instOptions() | forcedInstOptions();
-
- if (options & BaseInst::kOptionReserved) {
- if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
-
-#ifndef ASMJIT_NO_VALIDATION
- // Strict validation.
- if (hasValidationOption(kValidationOptionIntermediate)) {
- Operand_ opArray[Globals::kMaxOpCount];
- EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
-
- Error err = InstAPI::validate(arch(), BaseInst(instId, options, _extraReg), opArray, opCount);
- if (ASMJIT_UNLIKELY(err)) {
- resetInstOptions();
- resetExtraReg();
- resetInlineComment();
- return reportError(err);
- }
- }
-#endif
-
- // Clear options that should never be part of `InstNode`.
- options &= ~BaseInst::kOptionReserved;
- }
-
- uint32_t opCapacity = InstNode::capacityOfOpCount(opCount);
- ASMJIT_ASSERT(opCapacity >= InstNode::kBaseOpCapacity);
-
- InstNode* node = _allocator.allocT<InstNode>(InstNode::nodeSizeOfOpCapacity(opCapacity));
- const char* comment = inlineComment();
-
- resetInstOptions();
- resetInlineComment();
-
- if (ASMJIT_UNLIKELY(!node)) {
- resetExtraReg();
- return reportError(DebugUtils::errored(kErrorOutOfMemory));
- }
-
- node = new(node) InstNode(this, instId, options, opCount, opCapacity);
- node->setExtraReg(extraReg());
- node->setOp(0, o0);
- node->setOp(1, o1);
- node->setOp(2, o2);
- for (uint32_t i = 3; i < opCount; i++)
- node->setOp(i, opExt[i - 3]);
- node->resetOpRange(opCount, opCapacity);
-
- if (comment)
- node->setInlineComment(static_cast<char*>(_dataZone.dup(comment, strlen(comment), true)));
-
- addNode(node);
- resetExtraReg();
- return kErrorOk;
-}
-
-// ============================================================================
-// [asmjit::BaseBuilder - Align]
-// ============================================================================
-
-Error BaseBuilder::align(uint32_t alignMode, uint32_t alignment) {
- if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
-
- AlignNode* node;
- ASMJIT_PROPAGATE(_newAlignNode(&node, alignMode, alignment));
-
- addNode(node);
- return kErrorOk;
-}
-
-// ============================================================================
-// [asmjit::BaseBuilder - Embed]
-// ============================================================================
-
-Error BaseBuilder::embed(const void* data, size_t dataSize) {
- if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
-
- EmbedDataNode* node;
- ASMJIT_PROPAGATE(_newEmbedDataNode(&node, Type::kIdU8, data, dataSize));
-
- addNode(node);
- return kErrorOk;
-}
-
-Error BaseBuilder::embedDataArray(uint32_t typeId, const void* data, size_t itemCount, size_t itemRepeat) {
- if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
-
- EmbedDataNode* node;
- ASMJIT_PROPAGATE(_newEmbedDataNode(&node, typeId, data, itemCount, itemRepeat));
-
- addNode(node);
- return kErrorOk;
-}
-
-Error BaseBuilder::embedConstPool(const Label& label, const ConstPool& pool) {
- if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
-
- if (!isLabelValid(label))
- return reportError(DebugUtils::errored(kErrorInvalidLabel));
-
- ASMJIT_PROPAGATE(align(kAlignData, uint32_t(pool.alignment())));
- ASMJIT_PROPAGATE(bind(label));
-
- EmbedDataNode* node;
- ASMJIT_PROPAGATE(_newEmbedDataNode(&node, Type::kIdU8, nullptr, pool.size()));
-
- pool.fill(node->data());
- addNode(node);
- return kErrorOk;
-}
-
-// EmbedLabel / EmbedLabelDelta
-// ----------------------------
-//
-// If dataSize is zero it means that the size is the same as target register
-// width, however, if it's provided we really want to validate whether it's
-// within the possible range.
-
-static inline bool BaseBuilder_checkDataSize(size_t dataSize) noexcept {
- return !dataSize || (Support::isPowerOf2(dataSize) && dataSize <= 8);
-}
-
-Error BaseBuilder::embedLabel(const Label& label, size_t dataSize) {
- if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
-
- if (!BaseBuilder_checkDataSize(dataSize))
- return reportError(DebugUtils::errored(kErrorInvalidArgument));
-
- EmbedLabelNode* node;
- ASMJIT_PROPAGATE(_newNodeT<EmbedLabelNode>(&node, label.id(), uint32_t(dataSize)));
-
- addNode(node);
- return kErrorOk;
-}
-
-Error BaseBuilder::embedLabelDelta(const Label& label, const Label& base, size_t dataSize) {
- if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
-
- if (!BaseBuilder_checkDataSize(dataSize))
- return reportError(DebugUtils::errored(kErrorInvalidArgument));
-
- EmbedLabelDeltaNode* node;
- ASMJIT_PROPAGATE(_newNodeT<EmbedLabelDeltaNode>(&node, label.id(), base.id(), uint32_t(dataSize)));
-
- addNode(node);
- return kErrorOk;
-}
-
-// ============================================================================
-// [asmjit::BaseBuilder - Comment]
-// ============================================================================
-
-Error BaseBuilder::comment(const char* data, size_t size) {
- if (ASMJIT_UNLIKELY(!_code))
- return DebugUtils::errored(kErrorNotInitialized);
-
- CommentNode* node;
- ASMJIT_PROPAGATE(_newCommentNode(&node, data, size));
-
- addNode(node);
- return kErrorOk;
-}
-
-// ============================================================================
-// [asmjit::BaseBuilder - Serialize]
-// ============================================================================
-
-Error BaseBuilder::serializeTo(BaseEmitter* dst) {
- Error err = kErrorOk;
- BaseNode* node_ = _firstNode;
-
- Operand_ opArray[Globals::kMaxOpCount];
-
- do {
- dst->setInlineComment(node_->inlineComment());
-
- if (node_->isInst()) {
- InstNode* node = node_->as<InstNode>();
-
- // NOTE: Inlined to remove one additional call per instruction.
- dst->setInstOptions(node->instOptions());
- dst->setExtraReg(node->extraReg());
-
- const Operand_* op = node->operands();
- const Operand_* opExt = EmitterUtils::noExt;
-
- uint32_t opCount = node->opCount();
- if (opCount > 3) {
- uint32_t i = 4;
- opArray[3] = op[3];
-
- while (i < opCount) {
- opArray[i].copyFrom(op[i]);
- i++;
- }
- while (i < Globals::kMaxOpCount) {
- opArray[i].reset();
- i++;
- }
- opExt = opArray + 3;
- }
-
- err = dst->_emit(node->id(), op[0], op[1], op[2], opExt);
- }
- else if (node_->isLabel()) {
- if (node_->isConstPool()) {
- ConstPoolNode* node = node_->as<ConstPoolNode>();
- err = dst->embedConstPool(node->label(), node->constPool());
- }
- else {
- LabelNode* node = node_->as<LabelNode>();
- err = dst->bind(node->label());
- }
- }
- else if (node_->isAlign()) {
- AlignNode* node = node_->as<AlignNode>();
- err = dst->align(node->alignMode(), node->alignment());
- }
- else if (node_->isEmbedData()) {
- EmbedDataNode* node = node_->as<EmbedDataNode>();
- err = dst->embedDataArray(node->typeId(), node->data(), node->itemCount(), node->repeatCount());
- }
- else if (node_->isEmbedLabel()) {
- EmbedLabelNode* node = node_->as<EmbedLabelNode>();
- err = dst->embedLabel(node->label(), node->dataSize());
- }
- else if (node_->isEmbedLabelDelta()) {
- EmbedLabelDeltaNode* node = node_->as<EmbedLabelDeltaNode>();
- err = dst->embedLabelDelta(node->label(), node->baseLabel(), node->dataSize());
- }
- else if (node_->isSection()) {
- SectionNode* node = node_->as<SectionNode>();
- err = dst->section(_code->sectionById(node->id()));
- }
- else if (node_->isComment()) {
- CommentNode* node = node_->as<CommentNode>();
- err = dst->comment(node->inlineComment());
- }
-
- if (err) break;
- node_ = node_->next();
- } while (node_);
-
- return err;
-}
-
-// ============================================================================
-// [asmjit::BaseBuilder - Events]
-// ============================================================================
-
-Error BaseBuilder::onAttach(CodeHolder* code) noexcept {
- ASMJIT_PROPAGATE(Base::onAttach(code));
-
- SectionNode* initialSection;
- Error err = sectionNodeOf(&initialSection, 0);
-
- if (!err)
- err = _passes.willGrow(&_allocator, 8);
-
- if (ASMJIT_UNLIKELY(err)) {
- onDetach(code);
- return err;
- }
-
- _cursor = initialSection;
- _firstNode = initialSection;
- _lastNode = initialSection;
- initialSection->setFlags(BaseNode::kFlagIsActive);
-
- return kErrorOk;
-}
-
-Error BaseBuilder::onDetach(CodeHolder* code) noexcept {
- BaseBuilder_deletePasses(this);
- _sectionNodes.reset();
- _labelNodes.reset();
-
- _allocator.reset(&_codeZone);
- _codeZone.reset();
- _dataZone.reset();
- _passZone.reset();
-
- _nodeFlags = 0;
-
- _cursor = nullptr;
- _firstNode = nullptr;
- _lastNode = nullptr;
-
- return Base::onDetach(code);
-}
-
-// ============================================================================
-// [asmjit::Pass - Construction / Destruction]
-// ============================================================================
-
-Pass::Pass(const char* name) noexcept
- : _cb(nullptr),
- _name(name) {}
-Pass::~Pass() noexcept {}
-
-ASMJIT_END_NAMESPACE
-
-#endif // !ASMJIT_NO_BUILDER