Compilation#
Platform#
-
type UNIT_Platform#
An integer encoding the target architecture and ABI. Constructed by bitwise OR of a
UNIT_Architectureand aUNIT_ABI.UNIT_Platform platform = UNIT_ARCH_AMD64 | UNIT_ABI_SYSTEMV;
-
enum UNIT_Architecture#
-
enumerator UNIT_ARCH_AMD64#
x86-64 (AMD64). This is the only architecture currently implemented.
-
enumerator UNIT_ARCH_AARCH64#
ARM64 (AArch64). Not yet implemented.
-
enumerator UNIT_ARCH_AMD64#
-
enum UNIT_ABI#
-
enumerator UNIT_ABI_SYSTEMV#
System V AMD64 ABI. Used on Linux, FreeBSD, and other Unix-like systems.
-
enumerator UNIT_ABI_WIN64#
Windows x64 calling convention. Not yet implemented.
-
enumerator UNIT_ABI_APPLE#
Apple ARM64 ABI. Not yet implemented.
-
enumerator UNIT_ABI_SYSTEMV#
-
UNIT_HOST_PLATFORM#
The platform of the current machine, auto-detected at compile time. This is the most common value to pass to
UNIT_Compile().UNIT_CompiledProcedure *compiled = UNIT_Compile(&proc, UNIT_HOST_PLATFORM);
-
UNIT_ABI UNIT_Platform_GET_ABI(UNIT_Platform platform)#
Extract the ABI from a platform value.
- Parameters:
platform – The platform.
- Returns:
The ABI component.
-
UNIT_Architecture UNIT_Platform_GET_ARCH(UNIT_Platform platform)#
Extract the architecture from a platform value.
- Parameters:
platform – The platform.
- Returns:
The architecture component.
Compiling#
-
UNIT_CompiledProcedure *UNIT_Compile(const UNIT_Procedure *procedure, UNIT_Platform platform)#
Compile a procedure to machine code. This translates the stack IR to register IR, performs register allocation, runs register IR optimization (unless
UNIT_FLAG_NO_OPTIMIZE_TRANSLATIONis set), and encodes the result as machine code.- Parameters:
procedure – The procedure to compile. Must have been optimized with
UNIT_Procedure_Optimize()first (optional but recommended).platform – The target platform.
- Returns:
A heap-allocated compiled procedure, or
NULLon failure. Must be freed withUNIT_CompiledProcedure_Free().
Example# UNIT_Procedure_Optimize(&proc); UNIT_CompiledProcedure *compiled = UNIT_Compile(&proc, UNIT_HOST_PLATFORM); if (compiled == NULL) { UNIT_PrintError(proc.context, stderr); return -1; } // Use compiled procedure ... UNIT_CompiledProcedure_Free(compiled);
-
struct UNIT_CompiledProcedure#
A compiled procedure containing machine code, ready for JIT execution or object file output.
-
UNIT_Context *context#
The context.
-
UNIT_Platform platform#
The target platform.
-
const char *name#
The procedure name.
-
UNIT_Context *context#
-
void UNIT_CompiledProcedure_Free(UNIT_CompiledProcedure *compiled)#
Free a compiled procedure. Safe to call with
NULL.- Parameters:
compiled – The compiled procedure to free, or
NULL.
Object files#
-
enum UNIT_ExecutableFormat#
-
enumerator UNIT_FORMAT_ELF#
ELF format (Linux, FreeBSD, etc). This is the only format currently implemented.
-
enumerator UNIT_FORMAT_MACHO#
Mach-O format (macOS). Not yet implemented.
-
enumerator UNIT_FORMAT_PE#
PE/COFF format (Windows). Not yet implemented.
-
enumerator UNIT_FORMAT_ELF#
-
UNIT_Status UNIT_CompiledProcedure_WriteObjectFile(const UNIT_CompiledProcedure *compiled, const char *path, UNIT_ExecutableFormat format)#
Write the compiled procedure to an object file. The resulting file can be linked with
gccorclang.- Parameters:
compiled – The compiled procedure.
path – The output file path.
format – The object file format.
Example# 1UNIT_CompiledProcedure_WriteObjectFile(compiled, "output.o", UNIT_FORMAT_ELF);Linking#gcc output.o -o output
JIT Compilation#
-
UNIT_ExecutableBuffer *UNIT_CompiledProcedure_JIT(const UNIT_CompiledProcedure *compiled, const UNIT_SymbolMap *symbol_map)#
JIT compile a procedure into executable memory. Returns an opaque buffer containing the compiled function.
Symbols referenced by
UNIT_OP_CALL_NAMEare resolved first from symbol_map (if provided), then viadlsym.- Parameters:
compiled – The compiled procedure.
symbol_map – Custom symbol resolution map, or
NULLto usedlsymonly.
- Returns:
A heap-allocated executable buffer, or
NULLon failure. Must be freed withUNIT_ExecutableBuffer_Free().
Example# UNIT_ExecutableBuffer *buf = UNIT_CompiledProcedure_JIT(compiled, NULL); if (buf == NULL) { UNIT_PrintError(compiled->context, stderr); return -1; } int64_t (*fn)(int64_t) = (int64_t (*)(int64_t))UNIT_ExecutableBuffer_GetPointer(buf); printf("%ld\n", fn(42)); UNIT_ExecutableBuffer_Free(buf);
-
type UNIT_ExecutableBuffer#
An opaque type representing JIT-compiled executable memory. The internal structure is not publicly visible.
-
void *UNIT_ExecutableBuffer_GetPointer(const UNIT_ExecutableBuffer *buffer)#
Get the function pointer from an executable buffer. Cast this to the appropriate function pointer type.
- Parameters:
buffer – The executable buffer.
- Returns:
A pointer to the compiled function.
-
void UNIT_ExecutableBuffer_Free(UNIT_ExecutableBuffer *buffer)#
Free an executable buffer and its mapped memory. Safe to call with
NULL.- Parameters:
buffer – The buffer to free, or
NULL.
Symbol maps#
-
struct UNIT_SymbolMap#
A map from symbol names to addresses, used for custom symbol resolution during JIT compilation. Useful for providing trampolines, callbacks, or calling between JIT-compiled functions.
-
UNIT_Context *context#
The context.
-
UNIT_Context *context#
-
UNIT_Status UNIT_SymbolMap_Init(UNIT_SymbolMap *symbol_map, UNIT_Context *context)#
Initialize a symbol map. On success,
UNIT_SymbolMap_Clear()must be called later.- Parameters:
symbol_map – A pointer to a symbol map.
context – The context.
-
UNIT_SymbolMap *UNIT_SymbolMap_New(UNIT_Context *context)#
Create a new heap-allocated symbol map. On success,
UNIT_SymbolMap_Free()must be called later.- Parameters:
context – The context.
- Returns:
A heap-allocated symbol map, or
NULLon failure.
-
void UNIT_SymbolMap_Clear(UNIT_SymbolMap *symbol_map)#
Free memory allocated by
UNIT_SymbolMap_Init().
-
void UNIT_SymbolMap_Free(UNIT_SymbolMap *symbol_map)#
Free memory allocated by
UNIT_SymbolMap_New(). Safe to call withNULL.
-
UNIT_Status UNIT_SymbolMap_RegisterSymbol(UNIT_SymbolMap *symbol_map, const char *name, void *address)#
Register a symbol name with its address. During JIT compilation, this address is used instead of
dlsymfor the given name.- Parameters:
symbol_map – The symbol map.
name – The symbol name.
address – The function pointer or data address.
Example# int64_t my_callback(int64_t x) { return x * 2; } UNIT_SymbolMap symbols; UNIT_SymbolMap_Init(&symbols, &ctx); UNIT_SymbolMap_RegisterSymbol(&symbols, "my_callback", (void *)my_callback); UNIT_ExecutableBuffer *buf = UNIT_CompiledProcedure_JIT(compiled, &symbols); // The compiled code can now call "my_callback" and it will // resolve to the function above. UNIT_SymbolMap_Clear(&symbols);
Debugging#
-
UNIT_Status UNIT_CompiledProcedure_PrintTranslatedIR(const UNIT_CompiledProcedure *compiled, FILE *stream)#
Print the register IR to a file stream. Shows the translation output after register allocation and optimization.
- Parameters:
compiled – The compiled procedure.
stream – The output stream (e.g.
stdout).
Example# UNIT_CompiledProcedure_PrintTranslatedIR(compiled, stdout);