IndexError Handling

Error Handling [¶]

Error handling.

Overview

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::handle_error() 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:

  • Record the error and continue (the way how the error is user-implemented).
  • Throw an exception. AsmJit doesn't use exceptions and is completely exception-safe, but it's perfectly legal to throw an exception from the error handler.
  • Use plain old C's setjmp() and longjmp(). Asmjit always puts Assembler, Builder and Compiler to a consistent state before calling ErrorHandler::handle_error(), 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 Arena allocated 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.

Using ErrorHandler [¶]

An example of attaching ErrorHandler to CodeHolder.

#include <asmjit/x86.h>
#include <stdio.h>
using namespace asmjit;
// A simple error handler implementation, extend according to your needs.
class MyErrorHandler : public ErrorHandler {
public:
void handle_error(Error err, const char* message, BaseEmitter* origin) override {
printf("AsmJit error: %s\n", message);
}
};
int main() {
MyErrorHandler myErrorHandler;
CodeHolder code;
code.init(rt.environment(), rt.cpu_features());
code.set_error_handler(&myErrorHandler);
x86::Assembler a(&code);
// ... code generation ...
return 0;
}

Useful classes in error handling group:

  • See DebugUtils that provides utilities useful for debugging.
  • See Error that lists error codes that AsmJit uses.
  • See ErrorHandler for more details about error handling.

Classes

Macros

Enumerations

Variables

#define ASMJIT_ASSERT(
...
)[¶]

Value:
((void)0)

AsmJit's own assert macro used in AsmJit code-base.

#define ASMJIT_NOT_REACHED()[¶]

Value:

Run-time assertion used in code that should never be reached.

#define ASMJIT_PROPAGATE(
...
)[¶]

Value:
do {
::asmjit::Error error_to_propagate = __VA_ARGS__;
if (ASMJIT_UNLIKELY(error_to_propagate != ::asmjit::Error::kOk)) {
return error_to_propagate;
}
} while (0)

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.

Error : uint32_tenum class[¶]

AsmJit error code.

ConstantDescription
kOk 

No error (success).

kOutOfMemory 

Out of memory.

kInvalidArgument 

Invalid argument.

kInvalidState 

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.

kInvalidArch 

Invalid or incompatible architecture.

kNotInitialized 

The object is not initialized.

kAlreadyInitialized 

The object is already initialized.

kFeatureNotEnabled 

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.

kTooManyHandles 

Too many handles (Windows) or file descriptors (Unix/Posix).

kTooLarge 

Code generated is larger than allowed.

kNoCodeGenerated 

No code generated.

Returned by runtime if the CodeHolder contains no code.

kInvalidDirective 

Invalid directive.

kInvalidLabel 

Attempt to use uninitialized label.

kTooManyLabels 

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.

kLabelAlreadyBound 

Label is already bound.

kLabelAlreadyDefined 

Label is already defined (named labels).

kLabelNameTooLong 

Label name is too long.

kInvalidLabelName 

Label must always be local if it's anonymous (without a name).

kInvalidParentLabel 

Parent id passed to CodeHolder::new_named_label_id() was either invalid or parent is not supported by the requested LabelType.

kInvalidSection 

Invalid section.

kTooManySections 

Too many sections (section index overflow).

kInvalidSectionName 

Invalid section name (most probably too long).

kTooManyRelocations 

Relocation index overflow (too many relocations).

kInvalidRelocEntry 

Invalid relocation entry.

kRelocOffsetOutOfRange 

Reloc entry contains address that is out of range (unencodable).

kInvalidAssignment 

Invalid assignment to a register, function argument, or function return value.

kInvalidInstruction 

Invalid instruction.

kInvalidRegType 

Invalid register type.

kInvalidRegGroup 

Invalid register group.

kInvalidPhysId 

Invalid physical register id.

kInvalidVirtId 

Invalid virtual register id.

kInvalidElementIndex 

Invalid element index (ARM).

kInvalidPrefixCombination 

Invalid prefix combination (X86|X64).

kInvalidLockPrefix 

Invalid LOCK prefix (X86|X64).

kInvalidXAcquirePrefix 

Invalid XACQUIRE prefix (X86|X64).

kInvalidXReleasePrefix 

Invalid XRELEASE prefix (X86|X64).

kInvalidRepPrefix 

Invalid REP prefix (X86|X64).

kInvalidRexPrefix 

Invalid REX prefix (X86|X64).

kInvalidExtraReg 

Invalid {...} register (X86|X64).

kInvalidKMaskUse 

Invalid {k} use (not supported by the instruction) (X86|X64).

kInvalidKZeroUse 

Invalid {k}{z} use (not supported by the instruction) (X86|X64).

kInvalidBroadcast 

Invalid broadcast - Currently only related to invalid use of AVX-512 {1tox} (X86|X64).

kInvalidEROrSAE 

Invalid 'embedded-rounding' {er} or 'suppress-all-exceptions' {sae} (AVX-512) (X86|X64).

kInvalidAddress 

Invalid address used (not encodable).

kInvalidAddressIndex 

Invalid index register used in memory address (not encodable).

kInvalidAddressScale 

Invalid address scale (not encodable).

kInvalidAddress64Bit 

Invalid use of 64-bit address.

kInvalidAddress64BitZeroExtension 

Invalid use of 64-bit address that require 32-bit zero-extension (X64).

kInvalidDisplacement 

Invalid displacement (not encodable).

kInvalidSegment 

Invalid segment (X86|X86_64).

kInvalidImmediate 

Invalid immediate (out of bounds on X86 and invalid pattern on ARM).

kInvalidOperandSize 

Invalid operand size.

kAmbiguousOperandSize 

Ambiguous operand size (memory has zero size while it's required to determine the operation type.

kOperandSizeMismatch 

Mismatching operand size (size of multiple operands doesn't match the operation size).

kInvalidOption 

Invalid option.

kOptionAlreadyDefined 

Option already defined.

kInvalidTypeId 

Invalid TypeId.

kInvalidUseOfGpbHi 

Invalid use of a 8-bit GPB-HIGH register.

kInvalidUseOfGpq 

Invalid use of a 64-bit GPQ register in 32-bit mode.

kInvalidUseOfF80 

Invalid use of an 80-bit float (TypeId::kFloat80).

kNotConsecutiveRegs 

Instruction requires the use of consecutive registers, but registers in operands weren't (AVX512, ASIMD load/store, etc...).

kConsecutiveRegsAllocation 

Failed to allocate consecutive registers - allocable registers either too restricted or a bug in RW info.

kIllegalVirtReg 

Illegal virtual register - reported by instruction validation.

kTooManyVirtRegs 

AsmJit cannot create more virtual registers.

kNoMorePhysRegs 

AsmJit requires a physical register, but no one is available.

kOverlappedRegs 

A variable has been assigned more than once to a function argument (BaseCompiler).

kOverlappingStackRegWithRegArg 

Invalid register to hold stack arguments offset.

kExpressionLabelNotBound 

Unbound label cannot be evaluated by expression.

kExpressionOverflow 

Arithmetic overflow during expression evaluation.

kFailedToOpenAnonymousMemory 

Failed to open anonymous memory handle or file descriptor.

kFailedToOpenFile 

Failed to open a file.

Note

This is a generic error that is used by internal filesystem API.

kProtectionFailure 

Protection failure can be returned from a virtual memory allocator or when trying to change memory access permissions.

kMaxValue 

Maximum value of a valid AsmJit Error code.