multi-level code generation abstraction with direct instruction emission
Provides three distinct emitter abstraction levels (BaseAssembler, BaseBuilder, BaseCompiler) that allow developers to choose between low-level direct instruction encoding to a CodeBuffer, intermediate node-based IR with reordering capabilities, or high-level virtual register allocation with automatic spilling. Each level inherits from the previous, enabling progressive complexity and automation while maintaining control over generated machine code at any abstraction tier.
Unique: Three-tier emitter hierarchy with inheritance-based composition allows seamless progression from raw instruction encoding (BaseAssembler) through IR-based optimization (BaseBuilder) to automated register management (BaseCompiler), all sharing unified operand and instruction APIs across x86/x64 and AArch64 backends without code duplication.
vs alternatives: Offers more granular control than LLVM's IR-only approach while maintaining higher-level abstractions than raw assemblers, enabling latency-sensitive JIT compilers to choose their abstraction level per code path.
architecture-agnostic instruction encoding with backend-specific opcode tables
Implements unified instruction encoding through architecture-specific backends (X86/X64 and AArch64) that use pre-generated opcode lookup tables and instruction signature matching. The X86 backend uses a table generation system that encodes instruction signatures, operand constraints, and opcode patterns into compact lookup structures; AArch64 uses similar table-driven encoding. A single instruction API call (e.g., `mov(dst, src)`) resolves to the correct machine code encoding based on operand types and target architecture.
Unique: Uses pre-generated instruction signature tables that encode operand constraints, size variants, and opcode patterns into compact lookup structures, enabling O(1) instruction resolution without runtime parsing or regex matching; X86 table generation system automatically derives signatures from ISA specifications.
vs alternatives: Faster instruction encoding than LLVM's table-driven approach due to simpler operand model; more maintainable than hand-coded switch statements because table generation is automated from ISA specs.
aarch64 instruction database with table-driven encoding
Implements AArch64 instruction support through a table-driven encoding system similar to x86/x64, with pre-generated instruction signatures and opcode patterns for AArch64 ISA. The AArch64 Instruction Database encodes instruction variants, operand constraints, and encoding rules into lookup tables. At runtime, instruction encoding resolves operand types to the correct AArch64 opcode and encoding format through signature matching.
Unique: Provides AArch64 instruction encoding through table-driven lookup matching x86/x64 architecture, enabling unified cross-architecture code generation APIs while maintaining architecture-specific instruction databases.
vs alternatives: Enables ARM64 code generation with the same API as x86-64, simplifying cross-platform JIT compiler development; more complete than minimal ARM64 assemblers due to comprehensive instruction coverage.
cross-platform virtual memory abstraction with platform-specific backends
Abstracts platform-specific virtual memory operations (mmap/mprotect on POSIX, VirtualAlloc/VirtualProtect on Windows) through a unified VirtMem interface. The abstraction handles page allocation, protection transitions, and memory deallocation across operating systems. Platform-specific implementations are selected at compile time based on detected OS, enabling single-source code to work on Linux, Windows, macOS, and other platforms.
Unique: Provides unified VirtMem interface that abstracts POSIX mmap/mprotect and Windows VirtualAlloc/VirtualProtect with compile-time platform selection, enabling W^X enforcement without platform-specific code in user code.
vs alternatives: More portable than OS-specific memory APIs while maintaining lower overhead than full abstraction layers; handles W^X enforcement transparently across platforms.
cmake-based modular build system with feature flags
Implements a CMake-based build system that enables fine-grained control over compiled features through feature flags (ASMJIT_BUILD_X86, ASMJIT_BUILD_ARM, etc.). Developers can selectively enable/disable architecture backends, instruction databases, and optional features at build time, reducing binary size and compilation time. The build system automatically detects platform capabilities and generates appropriate compiler flags.
Unique: Uses CMake feature flags to enable selective compilation of architecture backends and optional features, allowing developers to build minimal asmjit instances for embedded systems or specific use cases without modifying source code.
vs alternatives: More flexible than monolithic builds while maintaining simpler configuration than autotools; enables binary size optimization for embedded systems.
automatic register allocation with virtual register abstraction
The BaseCompiler emitter provides virtual register allocation by allowing developers to request unlimited virtual registers (VReg) that are automatically mapped to physical registers and spilled to stack as needed. The allocator tracks register liveness, performs greedy allocation, and inserts spill/reload instructions transparently. This abstraction hides the complexity of manual register management while maintaining control over register-level optimizations through explicit virtual register declarations.
Unique: Provides virtual register abstraction at the emitter level (not IR level), allowing direct instruction emission with automatic physical register mapping and transparent spilling, eliminating the need for separate IR-to-assembly lowering passes while maintaining single-pass code generation.
vs alternatives: Simpler API than LLVM's register allocator (no need to understand interference graphs) while still supporting complex register pressure scenarios; faster compilation than graph-coloring allocators due to greedy strategy.
executable memory management with w^x security enforcement
Manages allocation and lifecycle of executable memory through JitRuntime and JitAllocator, enforcing Write-XOR-Execute (W^X) security semantics where memory is either writable or executable, never both simultaneously. The VirtMem layer abstracts platform-specific virtual memory APIs (mmap on POSIX, VirtualAlloc on Windows) and handles page protection transitions. Code is written to writable memory, then protected as executable before execution, preventing code injection attacks.
Unique: Implements W^X enforcement at the allocator level with platform abstraction (VirtMem) that unifies POSIX mmap/mprotect and Windows VirtualAlloc/VirtualProtect, ensuring security guarantees across operating systems without exposing platform-specific APIs to users.
vs alternatives: Provides stronger security guarantees than manual mprotect calls (prevents TOCTOU attacks) while maintaining lower overhead than full sandboxing; more portable than OS-specific memory APIs.
node-based intermediate representation with instruction reordering and optimization
BaseBuilder emits instructions as nodes in a linked list (Node system) rather than directly to a buffer, enabling instruction reordering, dead code elimination, and optimization passes before final encoding. Each instruction becomes a Node with metadata about operands, dependencies, and side effects. Nodes can be inserted, removed, or reordered before the builder finalizes code, converting the node graph to machine code through the emitter hierarchy.
Unique: Uses a linked-list node representation that preserves instruction order while enabling arbitrary reordering and optimization before finalization, avoiding the complexity of full IR graphs (like LLVM) while maintaining single-pass code generation semantics.
vs alternatives: Lighter-weight than LLVM's SSA IR (lower memory overhead, faster compilation) while still enabling instruction reordering; more flexible than BaseAssembler's direct emission for optimization-focused use cases.
+5 more capabilities