AsmJit development is currently on hold due to insufficient funding. For more information, please see the Funding Page.
AsmJit is a lightweight C++ library for low-latency machine code generation. It supports X86, X86_64, and AArch64 architectures, and provides a type-safe API that enables semantic checks at compile time. An optional register allocator is included to make it easy to start generating machine code without a significant development effort.
AsmJit project, as the name implies, started as a library to allow JIT code generation and execution. However, AsmJit evolved and now contains features that are far beyond the initial scope. AsmJit now consists of multiple projects:
When consuming AsmJit as a dependency via package managers, please make sure that you are using a recent version. For convenience, the following links can be used to verify the versions offered by the most used package managers:
We don't recommend vcpkg at the moment as it has never offered an up-to-date AsmJit. In such cases, consider either vendoring it yourself or using a different way of obtaining it such as git submodule or git clone. AsmJit was designed to be easily embeddable in projects so it should not be an issue. CMake users can just include AsmJit project and pass asmjit::asmjit
as a library into target_link_libraries()
function.
When you see a commit starting with [bug]
in AsmJit master branch it's always time to update. Master branch should always be considered stable and for production use. Similarly, if your package manager offers a version that is older (bugs were fixed afterwards) such version is outdated and basically unsupported.
The example below demonstrates how AsmJit separates concepts used during code generation. Check out AsmJit's documentation for more details and code snippets.
#include <asmjit/x86.h>
#include <stdio.h>
using namespace asmjit;
// Signature of the generated function.
typedef int (*Func)(void);
int main(int argc, char* argv[]) {
// Runtime designed for JIT - it holds relocated functions and controls their lifetime.
JitRuntime rt;
// Holds code and relocation information during code generation.
CodeHolder code;
// Code holder must be initialized before it can be used. The simples way to initialize
// it is to use 'Environment' from JIT runtime, which matches the target architecture,
// operating system, ABI, and other important properties.
code.init(rt.environment(), rt.cpu_features());
// Emitters can emit code to CodeHolder - let's create 'x86::Assembler', which can emit
// either 32-bit (x86) or 64-bit (x86_64) code. The following line also attaches the
// assembler to CodeHolder, which calls 'code.attach(&a)' implicitly.
x86::Assembler a(&code);
// Use the x86::Assembler to emit some code to .text section in CodeHolder:
a.mov(x86::eax, 1); // Emits 'mov eax, 1' - moves one to 'eax' register.
a.ret(); // Emits 'ret' - returns from a function.
// 'x86::Assembler' is no longer needed from here and can be destroyed or explicitly
// detached via 'code.detach(&a)' - which detaches an attached emitter from code holder.
// Now add the generated code to JitRuntime via JitRuntime::add(). This function would
// copy the code from CodeHolder into memory with executable permission and relocate it.
Func fn;
Error err = rt.add(&fn, &code);
// It's always a good idea to handle errors, especially those returned from the Runtime.
if (err != Error::kOk) {
printf("AsmJit failed: %s\n", DebugUtils::error_as_string(err));
return 1;
}
// CodeHolder is no longer needed from here and can be safely destroyed. The runtime now
// holds the relocated function, which we have generated, and controls its lifetime. The
// function will be freed with the runtime, so it's necessary to keep the runtime around.
//
// Use 'code.reset()' to explicitly free CodeHolder's content when necessary.
// Execute the generated function and print the resulting '1', which it moves to 'eax'.
int result = fn();
printf("%d\n", result);
// All classes use RAII, all resources will be released before `main()` returns, the
// generated function can be, however, released explicitly if you intend to reuse or
// keep the runtime alive, which you should in a production-ready code.
rt.release(fn);
return 0;
}
Check out Build Instructions page that explains how to build and consume AsmJit. Please note that AsmJit uses dynamic linking by default, so in order to use AsmJit statically define ASMJIT_STATIC
in all compilation units that use AsmJit (or at a build level, which is simpler). When consuming AsmJit via cmake, use just asmjit::asmjit
as a dependency, which would setup everything required to successfully consume the library. Check out CMake Integration section for more details.
AsmJit has been the preferred choice of many projects for years, because of its API, small size, and many features packed into it. It's ideal for implementing high performance and low latency code generators, be it JIT backends of programming languages, recompilers, or specialized compilers that generate code based on data that is only known at runtime. AsmJit has been also successfully used in other domains such as debuggers, reverse engineering tools, and computer graphics.
If you would like to add a commercial product on the list above, please use our Support page and contact the author of AsmJit. The email must contain the product that uses AsmJit, the company, link to the product or a company homepage, and a permission to list the product on AsmJit homepage. Alternatively, if the information about the use of AsmJit in a product is known publicly (a company blog, product changelogs, announcements, etc...) that's sufficient for the inclusion as well.
AsmJit developers would like to thank all companies and individuals that support its development and maintenance.
We would like to specially thank Shiguredo Inc. for a long-term support of AsmJit.
Developing AsmJit requires significant time and effort, which can no longer be offered for free. Organizations that depend on AsmJit in their products or infrastructure are encouraged to support its ongoing development. This helps ensure the software remains actively maintained, reliable, and free of issues that could impact them. For more information and contacts, please see AsmJit's Support page.
Details regarding AsmJit's funding status can be found on the author's Funding page.