Skip to main content

Module abi

Module abi 

Source
Expand description

Common ABI trait and utilities for code generation backends.

A trait that all ABI implementations must follow, reducing code duplication and giving a consistent interface.

§Application Binary Interface (ABI) Overview

Lamina uses platform C ABIs for function calls. The ABI implementation is abstracted through the Abi trait, which gives a consistent interface across all backends.

§Common ABI Contract

§Function Name Mangling

All backends apply platform-specific symbol mangling:

  • macOS: Functions are prefixed with underscore (e.g., main → _main)
  • Linux/Windows: Functions use their original names (e.g., main → main)

The mangle_function_name() method handles this automatically.

§Argument Passing

  • Arguments are passed using the platform C ABI register order
  • Overflow arguments (beyond register capacity) are spilled to the stack
  • Integer arguments use 64-bit slots, even for narrower integer types (i8, i16, i32)
  • Floating-point arguments follow platform-specific rules

Example: Function call with 3 arguments (RISC-V)

# Arguments: a0=arg1, a1=arg2, a2=arg3
mv a0, t0        # Load arg1 to a0
mv a1, t1        # Load arg2 to a1
mv a2, t2        # Load arg3 to a2
call my_function # Call function

Example: Function call with 10 arguments (x86_64 System V)

# First 6 args in registers: rdi, rsi, rdx, rcx, r8, r9
# Remaining 4 args on stack (16-byte aligned)
mov %rdi, %rax   # arg1
mov %rsi, %rbx   # arg2
# ... args 3-6 in rdx, rcx, r8, r9
push %r10        # arg7 on stack
push %r11        # arg8 on stack
push %r12        # arg9 on stack
push %r13        # arg10 on stack
call my_function
add $32, %rsp    # Clean up stack

§Return Values

  • Integer return values use the C ABI integer return register
  • Floating-point return values use the FP return register (if applicable)
  • Void functions return nothing

Example: Return value handling

# RISC-V: return value in a0 (integer) or fa0 (float)
call my_function
mv t0, a0        # Save integer return value

# x86_64: return value in rax (integer) or xmm0 (float)
call my_function
mov %rax, %rbx   # Save integer return value

§Builtin Functions

Builtin functions can be overridden via the LAMINA_BUILTINS environment variable:

LAMINA_BUILTINS="malloc=jemalloc_malloc,dealloc=jemalloc_free"

Every runtime helper the compiler calls is a RuntimeSymbol. Keys are the C names (malloc, free, exit, memcpy, memmove, memset), plus the legacy alias dealloc (free). The compiler-rt routines for 128-bit integers (__divti3, __floattidf, …) are keys too, so an embedder can supply them. Platform decoration (_free on macOS) is applied to the override as well.

§Backend-Specific ABIs

See the documentation in each backend’s ABI module:

  • x86_64::abi - System V AMD64 and Microsoft x64
  • aarch64::abi - AAPCS64
  • riscv::abi - RISC-V calling convention
  • wasm::abi - WebAssembly stack-based calling

Structs§

BuiltinLibrary
Resolves runtime helper names to the symbols the emitted code must reference.

Enums§

BuiltinOverrideError
Why a LAMINA_BUILTINS value could not be read.
RuntimeSymbol
Runtime helpers the compiler calls by name.

Traits§

Abi
Trait defining the common interface for all ABI implementations.

Functions§

common_call_stub
Helper function to create a common call_stub implementation.
get_free_symbol
Helper function to get the platform-specific free symbol name.
get_malloc_symbol
Helper function to get the platform-specific malloc symbol name.
get_printf_symbol
Helper function to get the platform-specific printf symbol name.
mangle_macos_name
Helper function to mangle function names for macOS (adds underscore prefix).
parse_builtin_overrides
Parses name=symbol,name=symbol.