lucia-lasm 2.1.0

LASM - Lucia Assembly Language
Documentation

LASM - Lucia Assembly Language

LASM (Lucia Assembly) is a Rust crate that provides JIT (Just-In-Time) compilation of a custom register-based assembly language into native machine code.

It is primarily designed to serve as a high-performance execution backend for interpreted or scripting programming languages, allowing them to JIT-compile performance-critical parts of the code at runtime.

Key Features

  • JIT using either Cranelift or LLVM backends
  • Seamless variable bridge - easily read/write variables between the host language and LASM code
  • Modern, clean assembly syntax with high-level syscalls
  • 64-bit register-based architecture (x86_64 + AArch64 support)
  • Meant to be embedded into interpreters / VMs / scripting runtimes

Why LASM?

Many interpreted languages suffer from performance bottlenecks in hot loops, math-heavy code, or data processing.

LASM is intended that the language designer exposes LASM compiling and calling to the language and then the users of the language can:

  • Compile LASM code into abstracted out identifiers
  • Call these abstracted out identifiers and get the output
  • Interact between language variables and values from lasm
  • Run heavy loops or calculations from native JIT code for faster execution

If you want to see an example of how LASM is integrated into a scripting language, see Lucia and it's LASM library

Backend Selection (Cargo Features)

LASM requires exactly one code-generation backend to be enabled:

[dependencies]

lasm = { version = "2", default-features = false, features = ["cranelift"], package = "lucia-lasm" }

# or

lasm = { version = "2", default-features = false, features = ["llvm"], package = "lucia-lasm" }

Available features:

  • cranelift - uses Cranelift (fast compilation, good runtime performance, smaller dependency footprint)
    (this is the default when no features are specified)
  • llvm - uses LLVM via the inkwell crate (potentially better optimizations, larger & slower compilation, requires llvm-17 installed)
  • dbg - enables extra debug checks, instruction tracing, and validation (makes execution significantly slower - only for development)

Important:
If neither cranelift nor llvm is enabled -> compile-time error
If both are enabled -> compile-time error

Installation

[dependencies]

lasm = { version = "2", package = "lucia-lasm" }

As an executable:

cargo install lucia-lasm

Basic Embedding Example

use lasm::{compile, call, Target, Value};
use std::collections::HashMap;

fn main() -> anyhow::Result<()> {
    let lasm_code = r#"
        load value, r0       ; read variable "value" from host
        mul r0, 2            ; value *= 2
        push r0, result      ; write back to host variable "result"
        mov 0, r0
        syscall exit
    "#;

    // Compile once - reuse the function many times
    let target = Target::Native;
    let module = compile(lasm_code, target)?;

    // Call many times with different inputs
    for i in 1..=5 {
        let mut vars = HashMap::new();
        vars.insert("value".to_string(), Value::Int(i));

        let exit_code = call(&module, &mut vars)?;

        if let Some(Value::Int(result)) = vars.get("result") {
            println!("Input: {} -> Result: {}", i, result); // -> 2, 4, 6, 8, 10
            assert_eq!(*result, i * 2);
        }

        assert_eq!(exit_code, 0);
    }

    Ok(())
}

Architecture & Highlights

  • Registers: r0–r15 (64-bit), rsp, rbp
  • Variable bridge:
    • load "name", reg - read from host
    • push reg, "name" - write to host
  • Float operations: fadd, fsub, fmul, ...
  • High-level syscalls: print_int, malloc, strcmp, time, rand, sleep, ...
  • Control flow: beq, bne, blt, call/ret, labels
  • Supported types (via Value enum): Int, Float, String, Ptr, Null

Current Status

  • Compiling for not Native target is not supported yet.
  • Cranelift backend is more lightweight and faster to compile lasm functions, slower to compile crate.
  • LLVM backend may give better peak performance on complex code (but slower compilation of lasm functions)
  • dbg feature is useful during language development but hurts performance

License

MIT

See LICENSE