AsmJit
Low-Latency Machine Code Generation
Error handling.
AsmJit uses error codes to represent and return errors. Every function that can fail returns an Error code. Exceptions are never thrown by AsmJit itself even in extreme conditions like out-of-memory, but it's possible to override ErrorHandler::handleError() to throw, in that case no error will be returned and exception will be thrown instead. All functions where this can happen are not marked noexcept
.
Errors should never be ignored, however, checking errors after each AsmJit API call would simply over-complicate the whole code generation experience. ErrorHandler exists to make the use of AsmJit API simpler as it allows to customize how errors can be handled:
setjmp()
and longjmp()
. Asmjit always puts Assembler, Builder and Compiler to a consistent state before calling ErrorHandler::handleError(), so longjmp()
can be used without issues to cancel the code-generation if an error occurred. This method can be used if exception handling in your project is turned off and you still want some comfort. In most cases it should be safe as AsmJit uses Zone memory and the ownership of memory it allocates always ends with the instance that allocated it. If using this approach please never jump outside the life-time of CodeHolder and BaseEmitter.An example of attaching ErrorHandler to CodeHolder.
Useful classes in error handling group:
AsmJit's own assert macro used in AsmJit code-base.
Propagates a possible Error
produced by ...
to the caller by returning the error immediately.
Used by AsmJit internally, but kept public for users that want to use the same technique to propagate errors to the caller.
AsmJit error type (uint32_t).
AsmJit error codes.
Constant | Description |
---|---|
kErrorOk | No error (success). |
kErrorOutOfMemory | Out of memory. |
kErrorInvalidArgument | Invalid argument. |
kErrorInvalidState | Invalid state. If this error is returned it means that either you are doing something wrong or AsmJit caught itself by doing something wrong. This error should never be ignored. |
kErrorInvalidArch | Invalid or incompatible architecture. |
kErrorNotInitialized | The object is not initialized. |
kErrorAlreadyInitialized | The object is already initialized. |
kErrorFeatureNotEnabled | Either a built-in feature was disabled at compile time and it's not available or the feature is not available on the target platform. For example trying to allocate large pages on unsupported platform would return this error. |
kErrorTooManyHandles | Too many handles (Windows) or file descriptors (Unix/Posix). |
kErrorTooLarge | Code generated is larger than allowed. |
kErrorNoCodeGenerated | No code generated. Returned by runtime if the CodeHolder contains no code. |
kErrorInvalidDirective | Invalid directive. |
kErrorInvalidLabel | Attempt to use uninitialized label. |
kErrorTooManyLabels | Label index overflow - a single BaseAssembler instance can hold almost 2^32 (4 billion) labels. If there is an attempt to create more labels then this error is returned. |
kErrorLabelAlreadyBound | Label is already bound. |
kErrorLabelAlreadyDefined | Label is already defined (named labels). |
kErrorLabelNameTooLong | Label name is too long. |
kErrorInvalidLabelName | Label must always be local if it's anonymous (without a name). |
kErrorInvalidParentLabel | Parent id passed to CodeHolder::newNamedLabelEntry() was either invalid or parent is not supported by the requested |
kErrorInvalidSection | Invalid section. |
kErrorTooManySections | Too many sections (section index overflow). |
kErrorInvalidSectionName | Invalid section name (most probably too long). |
kErrorTooManyRelocations | Relocation index overflow (too many relocations). |
kErrorInvalidRelocEntry | Invalid relocation entry. |
kErrorRelocOffsetOutOfRange | Reloc entry contains address that is out of range (unencodable). |
kErrorInvalidAssignment | Invalid assignment to a register, function argument, or function return value. |
kErrorInvalidInstruction | Invalid instruction. |
kErrorInvalidRegType | Invalid register type. |
kErrorInvalidRegGroup | Invalid register group. |
kErrorInvalidPhysId | Invalid physical register id. |
kErrorInvalidVirtId | Invalid virtual register id. |
kErrorInvalidElementIndex | Invalid element index (ARM). |
kErrorInvalidPrefixCombination | Invalid prefix combination (X86|X64). |
kErrorInvalidLockPrefix | Invalid LOCK prefix (X86|X64). |
kErrorInvalidXAcquirePrefix | Invalid XACQUIRE prefix (X86|X64). |
kErrorInvalidXReleasePrefix | Invalid XRELEASE prefix (X86|X64). |
kErrorInvalidRepPrefix | Invalid REP prefix (X86|X64). |
kErrorInvalidRexPrefix | Invalid REX prefix (X86|X64). |
kErrorInvalidExtraReg | Invalid {...} register (X86|X64). |
kErrorInvalidKMaskUse | Invalid {k} use (not supported by the instruction) (X86|X64). |
kErrorInvalidKZeroUse | Invalid {k}{z} use (not supported by the instruction) (X86|X64). |
kErrorInvalidBroadcast | Invalid broadcast - Currently only related to invalid use of AVX-512 {1tox} (X86|X64). |
kErrorInvalidEROrSAE | Invalid 'embedded-rounding' {er} or 'suppress-all-exceptions' {sae} (AVX-512) (X86|X64). |
kErrorInvalidAddress | Invalid address used (not encodable). |
kErrorInvalidAddressIndex | Invalid index register used in memory address (not encodable). |
kErrorInvalidAddressScale | Invalid address scale (not encodable). |
kErrorInvalidAddress64Bit | Invalid use of 64-bit address. |
kErrorInvalidAddress64BitZeroExtension | Invalid use of 64-bit address that require 32-bit zero-extension (X64). |
kErrorInvalidDisplacement | Invalid displacement (not encodable). |
kErrorInvalidSegment | Invalid segment (X86). |
kErrorInvalidImmediate | Invalid immediate (out of bounds on X86 and invalid pattern on ARM). |
kErrorInvalidOperandSize | Invalid operand size. |
kErrorAmbiguousOperandSize | Ambiguous operand size (memory has zero size while it's required to determine the operation type. |
kErrorOperandSizeMismatch | Mismatching operand size (size of multiple operands doesn't match the operation size). |
kErrorInvalidOption | Invalid option. |
kErrorOptionAlreadyDefined | Option already defined. |
kErrorInvalidTypeId | Invalid TypeId. |
kErrorInvalidUseOfGpbHi | Invalid use of a 8-bit GPB-HIGH register. |
kErrorInvalidUseOfGpq | Invalid use of a 64-bit GPQ register in 32-bit mode. |
kErrorInvalidUseOfF80 | Invalid use of an 80-bit float (TypeId::kFloat80). |
kErrorNotConsecutiveRegs | Instruction requires the use of consecutive registers, but registers in operands weren't (AVX512, ASIMD load/store, etc...). |
kErrorConsecutiveRegsAllocation | Failed to allocate consecutive registers - allocable registers either too restricted or a bug in RW info. |
kErrorIllegalVirtReg | Illegal virtual register - reported by instruction validation. |
kErrorTooManyVirtRegs | AsmJit cannot create more virtual registers. |
kErrorNoMorePhysRegs | AsmJit requires a physical register, but no one is available. |
kErrorOverlappedRegs | A variable has been assigned more than once to a function argument (BaseCompiler). |
kErrorOverlappingStackRegWithRegArg | Invalid register to hold stack arguments offset. |
kErrorExpressionLabelNotBound | Unbound label cannot be evaluated by expression. |
kErrorExpressionOverflow | Arithmetic overflow during expression evaluation. |
kErrorFailedToOpenAnonymousMemory | Failed to open anonymous memory handle or file descriptor. |
kErrorFailedToOpenFile | Failed to open a file.
|
kErrorProtectionFailure | Protection failure can be returned from a virtual memory allocator or when trying to change memory access permissions. |
kErrorCount | Count of AsmJit error codes. |