asmjit::BaseBuilder Class Reference

Builder interface.

BaseBuilder interface was designed to be used as a BaseAssembler replacement in case pre-processing or post-processing of the generated code is required. The code can be modified during or after code generation. Pre or post processing can be done manually or through a Pass object. BaseBuilder stores the emitted code as a double-linked list of nodes, which allows O(1) insertion and removal during processing.

Check out architecture specific builders for more details and examples:

Public Members

- Public Attributes inherited from asmjit::BaseEmitter

Public Types

- Public Types inherited from asmjit::BaseEmitter

Member Functions

Construction & Destruction
Node Management
Section Management
Label Management
Passes
Emit
Align
Embed
Comment
Serialization
Events
- Public Member Functions inherited from asmjit::BaseEmitter

Constructor & Destructor Documentation

BaseBuilder::BaseBuilder()noexcept

Creates a new BaseBuilder instance.

BaseBuilder::~BaseBuilder()virtualnoexcept

Destroys the BaseBuilder instance.

Member Function Documentation

BaseNode* BaseBuilder::firstNode() constnoexcept

Returns the first node.

BaseNode* BaseBuilder::lastNode() constnoexcept

Returns the last node.

template<typename T, typename... Args>
Error BaseBuilder::_newNodeT(T** out, Args&&... args)

Allocates and instantiates a new node of type T and returns its instance.

If the allocation fails nullptr is returned.

The template argument T must be a type that is extends BaseNode.

Remarks
The pointer returned (if non-null) is owned by the Builder or Compiler. When the Builder/Compiler is destroyed it destroys all nodes it created so no manual memory management is required.

Error BaseBuilder::_newInstNode(InstNode** out, uint32_t instId, uint32_t instOptions, uint32_t opCount)

Creates a new InstNode.

Error BaseBuilder::_newLabelNode(LabelNode** out)

Creates a new LabelNode.

Error BaseBuilder::_newAlignNode(AlignNode** out, uint32_t alignMode, uint32_t alignment)

Creates a new AlignNode.

Error BaseBuilder::_newEmbedDataNode(EmbedDataNode** out, uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount = 1)

Creates a new EmbedDataNode.

Error BaseBuilder::_newConstPoolNode(ConstPoolNode** out)

Creates a new ConstPoolNode.

Error BaseBuilder::_newCommentNode(CommentNode** out, const char* data, size_t size)

Creates a new CommentNode.

BaseNode* BaseBuilder::addNode(BaseNode* node)noexcept

Adds node after the current and sets the current node to the given node.

BaseNode* BaseBuilder::addAfter(BaseNode* node, BaseNode* ref)noexcept

Inserts the given node after ref.

BaseNode* BaseBuilder::addBefore(BaseNode* node, BaseNode* ref)noexcept

Inserts the given node before ref.

BaseNode* BaseBuilder::removeNode(BaseNode* node)noexcept

Removes the given node.

void BaseBuilder::removeNodes(BaseNode* first, BaseNode* last)noexcept

Removes multiple nodes.

BaseNode* BaseBuilder::cursor() constnoexcept

Returns the cursor.

When the Builder/Compiler is created it automatically creates a '.text' SectionNode, which will be the initial one. When instructions are added they are always added after the cursor and the cursor is changed to be that newly added node. Use setCursor() to change where new nodes are inserted.

BaseNode* BaseBuilder::setCursor(BaseNode* node)noexcept

Sets the current node to node and return the previous one.

void BaseBuilder::_setCursor(BaseNode* node)noexcept

Sets the current node without returning the previous node.

Only use this function if you are concerned about performance and want this inlined (for example if you set the cursor in a loop, etc...).

const ZoneVector<SectionNode*>& BaseBuilder::sectionNodes() constnoexcept

Returns a vector of SectionNode objects.

Note
If a section of some id is not associated with the Builder/Compiler it would be null, so always check for nulls if you iterate over the vector.

bool BaseBuilder::hasRegisteredSectionNode(uint32_t sectionId) constnoexcept

Tests whether the SectionNode of the given sectionId was registered.

Error BaseBuilder::sectionNodeOf(SectionNode** out, uint32_t sectionId)

Returns or creates a SectionNode that matches the given sectionId.

Remarks
This function will either get the existing SectionNode or create it in case it wasn't created before. You can check whether a section has a registered SectionNode by using BaseBuilder::hasRegisteredSectionNode().

bool BaseBuilder::hasDirtySectionLinks() constnoexcept

Returns whether the section links of active section nodes are dirty.

You can update these links by calling updateSectionLinks() in such case.

void BaseBuilder::updateSectionLinks()noexcept

Updates links of all active section nodes.

const ZoneVector<LabelNode*>& BaseBuilder::labelNodes() constnoexcept

Returns a vector of LabelNode nodes.

Note
If a label of some id is not associated with the Builder/Compiler it would be null, so always check for nulls if you iterate over the vector.

bool BaseBuilder::hasRegisteredLabelNode(uint32_t labelId) constnoexcept[1/2]

Tests whether the LabelNode of the given labelId was registered.

bool BaseBuilder::hasRegisteredLabelNode(const Label& label) constnoexcept[2/2]

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Error BaseBuilder::labelNodeOf(LabelNode** out, uint32_t labelId)[1/2]

Gets or creates a LabelNode that matches the given labelId.

Remarks
This function will either get the existing LabelNode or create it in case it wasn't created before. You can check whether a label has a registered LabelNode by calling BaseBuilder::hasRegisteredLabelNode().

Error BaseBuilder::labelNodeOf(LabelNode** out, const Label& label)[2/2]

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Error BaseBuilder::registerLabelNode(LabelNode* node)

Registers this LabelNode (internal).

This function is used internally to register a newly created LabelNode with this instance of Builder/Compiler. Use labelNodeOf() functions to get back LabelNode from a label or its identifier.

Label BaseBuilder::newLabel()override

Creates a new label.

Implements asmjit::BaseEmitter.

Label BaseBuilder::newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, uint32_t type = Label::kTypeGlobal, uint32_t parentId = Globals::kInvalidId)override

Creates a new named label.

Implements asmjit::BaseEmitter.

Error BaseBuilder::bind(const Label& label)override

Binds the label to the current position of the current section.

Note
Attempt to bind the same label multiple times will return an error.

Implements asmjit::BaseEmitter.

const ZoneVector<Pass*>& BaseBuilder::passes() constnoexcept

Returns a vector of Pass instances that will be executed by runPasses().

template<typename T>
T* BaseBuilder::newPassT()noexcept[1/2]

Allocates and instantiates a new pass of type T and returns its instance.

If the allocation fails nullptr is returned.

The template argument T must be a type that is extends Pass.

Remarks
The pointer returned (if non-null) is owned by the Builder or Compiler. When the Builder/Compiler is destroyed it destroys all passes it created so no manual memory management is required.

template<typename T, typename... Args>
T* BaseBuilder::newPassT(Args&&... args)noexcept[2/2]

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Pass* BaseBuilder::passByName(const char* name) constnoexcept

Returns Pass by name.

If the pass having the given name doesn't exist nullptr is returned.

Error BaseBuilder::addPass(Pass* pass)noexcept

Adds pass to the list of passes.

Error BaseBuilder::deletePass(Pass* pass)noexcept

Removes pass from the list of passes and delete it.

Error BaseBuilder::runPasses()

Runs all passes in order.

Error BaseBuilder::align(uint32_t alignMode, uint32_t alignment)override

Aligns the current CodeBuffer position to the alignment specified.

The sequence that is used to fill the gap between the aligned location and the current location depends on the align mode, see AlignMode.

Implements asmjit::BaseEmitter.

Error BaseBuilder::embed(const void* data, size_t dataSize)override

Embeds raw data into the CodeBuffer.

Implements asmjit::BaseEmitter.

Error BaseBuilder::embedDataArray(uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount = 1)override

Embeds a typed data array.

This is the most flexible function for embedding data as it allows to:

  • Assign a typeId to the data, so the emitter knows the type of items stored in data. Binary data should use Type::kIdU8.
  • Repeat the given data repeatCount times, so the data can be used as a fill pattern for example, or as a pattern used by SIMD instructions.

Implements asmjit::BaseEmitter.

Error BaseBuilder::embedConstPool(const Label& label, const ConstPool& pool)override

Embeds a constant pool at the current offset by performing the following:

  1. Aligns by using kAlignData to the minimum pool alignment.
  2. Binds the ConstPool label so it's bound to an aligned location.
  3. Emits ConstPool content.

Implements asmjit::BaseEmitter.

Error BaseBuilder::embedLabel(const Label& label, size_t dataSize = 0)override

Embeds an absolute label address as data.

The dataSize is an optional argument that can be used to specify the size of the address data. If it's zero (default) the address size is deduced from the target architecture (either 4 or 8 bytes).

Implements asmjit::BaseEmitter.

Error BaseBuilder::embedLabelDelta(const Label& label, const Label& base, size_t dataSize = 0)override

Embeds a delta (distance) between the label and base calculating it as label - base.

This function was designed to make it easier to embed lookup tables where each index is a relative distance of two labels.

Implements asmjit::BaseEmitter.

Error BaseBuilder::comment(const char* data, size_t size = SIZE_MAX)override

Emits a comment stored in data with an optional size parameter.

Implements asmjit::BaseEmitter.

Error BaseBuilder::serializeTo(BaseEmitter* dst)

Serializes everything the given emitter dst.

Although not explicitly required the emitter will most probably be of Assembler type. The reason is that there is no known use of serializing nodes held by Builder/Compiler into another Builder-like emitter.

Error BaseBuilder::onAttach(CodeHolder* code)overridenoexcept

Called after the emitter was attached to CodeHolder.

Implements asmjit::BaseEmitter.

Reimplemented in asmjit::x86::Compiler, asmjit::BaseCompiler, and asmjit::x86::Builder.

Error BaseBuilder::onDetach(CodeHolder* code)overridenoexcept

Called after the emitter was detached from CodeHolder.

Implements asmjit::BaseEmitter.

Reimplemented in asmjit::BaseCompiler.

Member Data Documentation

Zone BaseBuilder::_codeZone

Base zone used to allocate nodes and passes.

Zone BaseBuilder::_dataZone

Data zone used to allocate data and names.

Zone BaseBuilder::_passZone

Pass zone, passed to Pass::run().

ZoneAllocator BaseBuilder::_allocator

Allocator that uses _codeZone.

ZoneVector<Pass*>BaseBuilder::_passes

Array of Pass objects.

ZoneVector<SectionNode*>BaseBuilder::_sectionNodes

Maps section indexes to LabelNode nodes.

ZoneVector<LabelNode*>BaseBuilder::_labelNodes

Maps label indexes to LabelNode nodes.

BaseNode* BaseBuilder::_cursor

Current node (cursor).

BaseNode* BaseBuilder::_firstNode

First node of the current section.

BaseNode* BaseBuilder::_lastNode

Last node of the current section.

uint32_t BaseBuilder::_nodeFlags

Flags assigned to each new node.

bool BaseBuilder::_dirtySectionLinks

The sections links are dirty (used internally).