lamina-codegen 0.1.2

Codegen utilities for Lamina (register allocation, ABI, frame management)
Documentation
//! WASM ABI utilities
//!
//! WASM has a more standardized ABI compared to native platforms,
//! but we still need utilities for function naming and module structure.

use crate::abi::Abi;
use lamina_mir::MirType;
use lamina_platform::TargetOperatingSystem;

/// Platform-specific ABI utilities for WASM code generation.
pub struct WasmABI {
    target_os: TargetOperatingSystem,
}

impl WasmABI {
    /// Creates a new ABI instance for the specified target OS.
    pub fn new(target_os: TargetOperatingSystem) -> Self {
        Self { target_os }
    }

    /// Get the WASM function name (currently just the original name).
    /// WASM doesn't require name mangling, but this method exists for consistency
    /// with other backends and future extensibility.
    pub fn mangle_function_name(&self, name: &str) -> String {
        name.to_string()
    }

    /// Get the WASM import for the print function.
    pub fn get_print_import(&self) -> &'static str {
        "(import \"console\" \"log\" (func $log (param i64)))\n  (import \"console\" \"logu\" (func $logu (param i64)))\n  (import \"console\" \"logf\" (func $logf (param f64)))"
    }

    /// Runtime helpers the backend calls but does not emit bodies for.
    pub fn get_runtime_imports(&self) -> &'static [&'static str] {
        &[
            "(import \"env\" \"writebyte\" (func $writebyte (param i64) (result i64)))",
            "(import \"env\" \"readbyte\" (func $readbyte (result i64)))",
            "(import \"env\" \"writeptr\" (func $writeptr (param i64 i64) (result i64)))",
            "(import \"env\" \"malloc\" (func $malloc (param i64) (result i64)))",
            "(import \"env\" \"free\" (func $free (param i64)))",
        ]
    }

    /// Get the WASM type for MIR types (currently only i64).
    pub fn get_wasm_type(&self, ty: &MirType) -> &'static str {
        let _ = ty;
        "i64"
    }

    /// Generate WASM global variable declaration for virtual registers.
    pub fn generate_global_decl(&self, index: usize) -> String {
        format!("  (global $vreg{index} (mut i64) (i64.const 0))")
    }

    /// Generate WASM local variable declaration.
    pub fn generate_local_decl(&self, index: usize) -> String {
        format!("    (local $l{index} i64)")
    }
}

impl Abi for WasmABI {
    fn target_os(&self) -> TargetOperatingSystem {
        self.target_os
    }

    fn mangle_function_name(&self, name: &str) -> String {
        WasmABI::mangle_function_name(self, name)
    }
}