asmjit::BaseEmitter Class Referenceabstract
Inheritance diagram for asmjit::BaseEmitter:
asmjit::a64::Emitter asmjit::BaseAssembler asmjit::BaseBuilder asmjit::x86::Emitter asmjit::a64::Assembler asmjit::x86::Assembler asmjit::a64::Builder asmjit::BaseCompiler asmjit::x86::Builder asmjit::a64::Compiler asmjit::x86::Compiler

Provides a base foundation to emitting code - specialized by BaseAssembler and BaseBuilder.

Public Members

Members

Classes

Member Functions

Construction & Destruction
Cast
Emitter Type & Flags
Target Information
Initialization & Finalization
Logging
Error Handling
Encoding Options
Diagnostic Options
Instruction Options
Sections
Labels
Emit
Emit Utilities
Align
Embed
Comment
Events

Member Function Documentation

EmitterType BaseEmitter::emitterType() constnoexcept

Returns the type of this emitter, see EmitterType.

EmitterFlags BaseEmitter::emitterFlags() constnoexcept

Returns emitter flags , see Flags.

bool BaseEmitter::isAssembler() constnoexcept

Tests whether the emitter inherits from BaseAssembler.

bool BaseEmitter::isBuilder() constnoexcept

Tests whether the emitter inherits from BaseBuilder.

Note
Both Builder and Compiler emitters would return true.

bool BaseEmitter::isCompiler() constnoexcept

Tests whether the emitter inherits from BaseCompiler.

bool BaseEmitter::hasEmitterFlag(EmitterFlags flag) constnoexcept

Tests whether the emitter has the given flag enabled.

bool BaseEmitter::isFinalized() constnoexcept

Tests whether the emitter is finalized.

bool BaseEmitter::isDestroyed() constnoexcept

Tests whether the emitter is destroyed (only used during destruction).

CodeHolder* BaseEmitter::code() constnoexcept

Returns the CodeHolder this emitter is attached to.

const Environment& BaseEmitter::environment() constnoexcept

Returns the target environment.

The returned Environment reference matches CodeHolder::environment().

bool BaseEmitter::is32Bit() constnoexcept

Tests whether the target architecture is 32-bit.

bool BaseEmitter::is64Bit() constnoexcept

Tests whether the target architecture is 64-bit.

Arch BaseEmitter::arch() constnoexcept

Returns the target architecture type.

SubArch BaseEmitter::subArch() constnoexcept

Returns the target architecture sub-type.

uint32_t BaseEmitter::registerSize() constnoexcept

Returns the target architecture's GP register size (4 or 8 bytes).

bool BaseEmitter::isInitialized() constnoexcept

Tests whether the emitter is initialized (i.e. attached to CodeHolder).

Error BaseEmitter::finalize()virtual

Finalizes this emitter.

Materializes the content of the emitter by serializing it to the attached CodeHolder through an architecture specific BaseAssembler. This function won't do anything if the emitter inherits from BaseAssembler as assemblers emit directly to a CodeBuffer held by CodeHolder. However, if this is an emitter that inherits from BaseBuilder or BaseCompiler then these emitters need the materialization phase as they store their content in a representation not visible to CodeHolder.

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

bool BaseEmitter::hasLogger() constnoexcept

Tests whether the emitter has a logger.

bool BaseEmitter::hasOwnLogger() constnoexcept

Tests whether the emitter has its own logger.

Own logger means that it overrides the possible logger that may be used by CodeHolder this emitter is attached to.

Logger* BaseEmitter::logger() constnoexcept

Returns the logger this emitter uses.

The returned logger is either the emitter's own logger or it's logger used by CodeHolder this emitter is attached to.

void BaseEmitter::setLogger(Logger* logger)noexcept

Sets or resets the logger of the emitter.

If the logger argument is non-null then the logger will be considered emitter's own logger, see hasOwnLogger() for more details. If the given logger is null then the emitter will automatically use logger that is attached to the CodeHolder this emitter is attached to.

void BaseEmitter::resetLogger()noexcept

Resets the logger of this emitter.

The emitter will bail to using a logger attached to CodeHolder this emitter is attached to, or no logger at all if CodeHolder doesn't have one.

bool BaseEmitter::hasErrorHandler() constnoexcept

Tests whether the emitter has an error handler attached.

bool BaseEmitter::hasOwnErrorHandler() constnoexcept

Tests whether the emitter has its own error handler.

Own error handler means that it overrides the possible error handler that may be used by CodeHolder this emitter is attached to.

ErrorHandler* BaseEmitter::errorHandler() constnoexcept

Returns the error handler this emitter uses.

The returned error handler is either the emitter's own error handler or it's error handler used by CodeHolder this emitter is attached to.

void BaseEmitter::setErrorHandler(ErrorHandler* errorHandler)noexcept

Sets or resets the error handler of the emitter.

void BaseEmitter::resetErrorHandler()noexcept

Resets the error handler.

Error BaseEmitter::reportError(Error err, const char* message = nullptr)

Handles the given error in the following way:

  1. If the emitter has ErrorHandler attached, it calls its ErrorHandler::handleError() member function first, and then returns the error. The handleError() function may throw.
  2. if the emitter doesn't have ErrorHandler, the error is simply returned.

EncodingOptions BaseEmitter::encodingOptions() constnoexcept

Returns encoding options.

bool BaseEmitter::hasEncodingOption(EncodingOptions option) constnoexcept

Tests whether the encoding option is set.

void BaseEmitter::addEncodingOptions(EncodingOptions options)noexcept

Enables the given encoding options.

void BaseEmitter::clearEncodingOptions(EncodingOptions options)noexcept

Disables the given encoding options.

DiagnosticOptions BaseEmitter::diagnosticOptions() constnoexcept

Returns the emitter's diagnostic options.

bool BaseEmitter::hasDiagnosticOption(DiagnosticOptions option) constnoexcept

Tests whether the given option is present in the emitter's diagnostic options.

void BaseEmitter::addDiagnosticOptions(DiagnosticOptions options)noexcept

Activates the given diagnostic options.

This function is used to activate explicit validation options that will be then used by all emitter implementations. There are in general two possibilities:

  • Architecture specific assembler is used. In this case a DiagnosticOptions::kValidateAssembler can be used to turn on explicit validation that will be used before an instruction is emitted. This means that internally an extra step will be performed to make sure that the instruction is correct. This is needed, because by default assemblers prefer speed over strictness.

    This option should be used in debug builds as it's pretty expensive.

  • Architecture specific builder or compiler is used. In this case the user can turn on DiagnosticOptions::kValidateIntermediate option that adds explicit validation step before the Builder or Compiler creates an InstNode to represent an emitted instruction. Error will be returned if the instruction is ill-formed. In addition, also DiagnosticOptions::kValidateAssembler can be used, which would not be consumed by Builder / Compiler directly, but it would be propagated to an architecture specific BaseAssembler implementation it creates during BaseEmitter::finalize().

void BaseEmitter::clearDiagnosticOptions(DiagnosticOptions options)noexcept

Deactivates the given validation options.

See addDiagnosticOptions() and DiagnosticOptions for more details.

InstOptions BaseEmitter::forcedInstOptions() constnoexcept

Returns forced instruction options.

Forced instruction options are merged with next instruction options before the instruction is encoded. These options have some bits reserved that are used by error handling, logging, and instruction validation purposes. Other options are globals that affect each instruction.

InstOptions BaseEmitter::instOptions() constnoexcept

Returns options of the next instruction.

void BaseEmitter::setInstOptions(InstOptions options)noexcept

Returns options of the next instruction.

void BaseEmitter::addInstOptions(InstOptions options)noexcept

Adds options of the next instruction.

void BaseEmitter::resetInstOptions()noexcept

Resets options of the next instruction.

bool BaseEmitter::hasExtraReg() constnoexcept

Tests whether the extra register operand is valid.

const RegOnly& BaseEmitter::extraReg() constnoexcept

Returns an extra operand that will be used by the next instruction (architecture specific).

void BaseEmitter::setExtraReg(const BaseReg& reg)noexcept[1/2]

Sets an extra operand that will be used by the next instruction (architecture specific).

void BaseEmitter::setExtraReg(const RegOnly& reg)noexcept[2/2]

Sets an extra operand that will be used by the next instruction (architecture specific).

void BaseEmitter::resetExtraReg()noexcept

Resets an extra operand that will be used by the next instruction (architecture specific).

const char* BaseEmitter::inlineComment() constnoexcept

Returns comment/annotation of the next instruction.

void BaseEmitter::setInlineComment(const char* s)noexcept

Sets comment/annotation of the next instruction.

Note
This string is set back to null by _emit(), but until that it has to remain valid as the Emitter is not required to make a copy of it (and it would be slow to do that for each instruction).

void BaseEmitter::resetInlineComment()noexcept

Resets the comment/annotation to nullptr.

Label BaseEmitter::newLabel()pure virtual

Creates a new label.

Implemented in asmjit::BaseBuilder, and asmjit::BaseAssembler.

Label BaseEmitter::newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, LabelType type = LabelType::kGlobal, uint32_t parentId = Globals::kInvalidId)pure virtual

Creates a new named label.

Implemented in asmjit::BaseBuilder, and asmjit::BaseAssembler.

Label BaseEmitter::newAnonymousLabel(const char* name, size_t nameSize = SIZE_MAX)

Creates a new anonymous label with a name, which can only be used for debugging purposes.

Label BaseEmitter::newExternalLabel(const char* name, size_t nameSize = SIZE_MAX)

Creates a new external label.

Label BaseEmitter::labelByName(const char* name, size_t nameSize = SIZE_MAX, uint32_t parentId = Globals::kInvalidId)noexcept

Returns Label by name.

Returns invalid Label in case that the name is invalid or label was not found.

Note
This function doesn't trigger ErrorHandler in case the name is invalid or no such label exist. You must always check the validity of the Label returned.

Error BaseEmitter::bind(const Label& label)pure virtual

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

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

Implemented in asmjit::BaseBuilder, and asmjit::BaseAssembler.

bool BaseEmitter::isLabelValid(uint32_t labelId) constnoexcept[1/2]

Tests whether the label id is valid (i.e. registered).

bool BaseEmitter::isLabelValid(const Label& label) constnoexcept[2/2]

Tests whether the label is valid (i.e. registered).

Error BaseEmitter::_emitI(InstId instId)[1/7]

Emits an instruction (internal).

Error BaseEmitter::_emitI(InstId instId, const Operand_& o0)[2/7]

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

Error BaseEmitter::_emitI(InstId instId, const Operand_& o0, const Operand_& o1)[3/7]

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

Error BaseEmitter::_emitI(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2)[4/7]

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

Error BaseEmitter::_emitI(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3)[5/7]

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

Error BaseEmitter::_emitI(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4)[6/7]

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

Error BaseEmitter::_emitI(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5)[7/7]

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

template<typename... Args>
Error BaseEmitter::emit(InstId instId, Args&&... operands)

Emits an instruction instId with the given operands.

Error BaseEmitter::align(AlignMode alignMode, uint32_t alignment)pure virtual

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. The alignment argument specifies alignment in bytes, so for example when it's 32 it means that the code buffer will be aligned to 32 bytes.

Implemented in asmjit::x86::Assembler, asmjit::BaseBuilder, and asmjit::a64::Assembler.

Error BaseEmitter::embed(const void* data, size_t dataSize)pure virtual

Embeds raw data into the CodeBuffer.

Implemented in asmjit::BaseBuilder, and asmjit::BaseAssembler.

Error BaseEmitter::embedDataArray(TypeId typeId, const void* data, size_t itemCount, size_t repeatCount = 1)pure virtual

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 TypeId::kUInt8.
  • 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.

Implemented in asmjit::BaseBuilder, and asmjit::BaseAssembler.

Error BaseEmitter::embedInt8(int8_t value, size_t repeatCount = 1)

Embeds int8_t value repeated by repeatCount.

Error BaseEmitter::embedUInt8(uint8_t value, size_t repeatCount = 1)

Embeds uint8_t value repeated by repeatCount.

Error BaseEmitter::embedInt16(int16_t value, size_t repeatCount = 1)

Embeds int16_t value repeated by repeatCount.

Error BaseEmitter::embedUInt16(uint16_t value, size_t repeatCount = 1)

Embeds uint16_t value repeated by repeatCount.

Error BaseEmitter::embedInt32(int32_t value, size_t repeatCount = 1)

Embeds int32_t value repeated by repeatCount.

Error BaseEmitter::embedUInt32(uint32_t value, size_t repeatCount = 1)

Embeds uint32_t value repeated by repeatCount.

Error BaseEmitter::embedInt64(int64_t value, size_t repeatCount = 1)

Embeds int64_t value repeated by repeatCount.

Error BaseEmitter::embedUInt64(uint64_t value, size_t repeatCount = 1)

Embeds uint64_t value repeated by repeatCount.

Error BaseEmitter::embedFloat(float value, size_t repeatCount = 1)

Embeds a floating point value repeated by repeatCount.

Error BaseEmitter::embedDouble(double value, size_t repeatCount = 1)

Embeds a floating point value repeated by repeatCount.

Error BaseEmitter::embedConstPool(const Label& label, const ConstPool& pool)pure virtual

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

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

Implemented in asmjit::BaseBuilder, and asmjit::BaseAssembler.

Error BaseEmitter::embedLabel(const Label& label, size_t dataSize = 0)pure virtual

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

Implemented in asmjit::BaseBuilder, and asmjit::BaseAssembler.

Error BaseEmitter::embedLabelDelta(const Label& label, const Label& base, size_t dataSize = 0)pure virtual

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.

Implemented in asmjit::BaseBuilder, and asmjit::BaseAssembler.

Error BaseEmitter::comment(const char* data, size_t size = SIZE_MAX)pure virtual

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

Implemented in asmjit::BaseBuilder, and asmjit::BaseAssembler.

Error BaseEmitter::commentf(const char* fmt, ...)

Emits a formatted comment specified by fmt and variable number of arguments.

Error BaseEmitter::commentv(const char* fmt, va_list ap)

Emits a formatted comment specified by fmt and ap.

Error BaseEmitter::onAttach(CodeHolder* code)pure virtualnoexcept

Error BaseEmitter::onDetach(CodeHolder* code)pure virtualnoexcept

void BaseEmitter::onSettingsUpdated()virtualnoexcept

Called when CodeHolder has updated an important setting, which involves the following:

This function ensures that the settings are properly propagated from CodeHolder to the emitter.

Note
This function is virtual and can be overridden, however, if you do so, always call BaseEmitter::onSettingsUpdated() within your own implementation to ensure that the emitter is in a consistent state.

Member Data Documentation

EmitterType BaseEmitter::_emitterType = EmitterType::kNone

EmitterFlags BaseEmitter::_emitterFlags = EmitterFlags::kNone

ValidationFlags BaseEmitter::_validationFlags = ValidationFlags::kNone

Validation flags in case validation is used.

Note
Validation flags are specific to the emitter and they are setup at construction time and then never changed.

DiagnosticOptions BaseEmitter::_diagnosticOptions = DiagnosticOptions::kNone

Validation options.

uint64_t BaseEmitter::_archMask = 0

All supported architectures in a bit-mask, where LSB is the bit with a zero index.

EncodingOptions BaseEmitter::_encodingOptions = EncodingOptions::kNone

Encoding options.

InstOptions BaseEmitter::_forcedInstOptions = InstOptions::kReserved

Forced instruction options, combined with _instOptions by emit().

uint32_t BaseEmitter::_privateData = 0

Internal private data used freely by any emitter.

CodeHolder* BaseEmitter::_code = nullptr

CodeHolder the emitter is attached to.

Logger* BaseEmitter::_logger = nullptr

Attached Logger.

ErrorHandler* BaseEmitter::_errorHandler = nullptr

Attached ErrorHandler.

Environment BaseEmitter::_environment {}

Describes the target environment, matches CodeHolder::environment().

OperandSignature BaseEmitter::_gpSignature {}

Native GP register signature and signature related information.

InstOptions BaseEmitter::_instOptions = InstOptions::kNone

Next instruction options (affects the next instruction).

RegOnly BaseEmitter::_extraReg {}

Extra register (op-mask {k} on AVX-512) (affects the next instruction).

const char* BaseEmitter::_inlineComment = nullptr

Inline comment of the next instruction (affects the next instruction).