Skip to main content

lamina_codegen/wasm/
abi.rs

1//! WASM ABI utilities
2//!
3//! WASM has a more standardized ABI compared to native platforms,
4//! but we still need utilities for function naming and module structure.
5
6use crate::abi::Abi;
7use lamina_mir::MirType;
8use lamina_platform::TargetOperatingSystem;
9
10/// Platform-specific ABI utilities for WASM code generation.
11pub struct WasmABI {
12    target_os: TargetOperatingSystem,
13}
14
15impl WasmABI {
16    /// Creates a new ABI instance for the specified target OS.
17    pub fn new(target_os: TargetOperatingSystem) -> Self {
18        Self { target_os }
19    }
20
21    /// Get the WASM function name (currently just the original name).
22    /// WASM doesn't require name mangling, but this method exists for consistency
23    /// with other backends and future extensibility.
24    pub fn mangle_function_name(&self, name: &str) -> String {
25        name.to_string()
26    }
27
28    /// Helpers the backend calls but emits no body for, each paired with the symbol a
29    /// call site names. A module that calls none of them imports none, so it needs no
30    /// host beyond what its own code asks for.
31    pub fn get_runtime_imports(&self) -> &'static [(&'static str, &'static str)] {
32        &[
33            (
34                "$writebyte",
35                "(import \"env\" \"writebyte\" (func $writebyte (param i64) (result i64)))",
36            ),
37            (
38                "$readbyte",
39                "(import \"env\" \"readbyte\" (func $readbyte (result i64)))",
40            ),
41            (
42                "$malloc",
43                "(import \"env\" \"malloc\" (func $malloc (param i64) (result i64)))",
44            ),
45            (
46                "$free",
47                "(import \"env\" \"free\" (func $free (param i64)))",
48            ),
49            (
50                "$write",
51                "(import \"env\" \"write\" (func $write (param i64 i64) (result i64)))",
52            ),
53            (
54                "$read",
55                "(import \"env\" \"read\" (func $read (param i64 i64) (result i64)))",
56            ),
57            (
58                "$memcpy",
59                "(import \"env\" \"memcpy\" (func $memcpy (param i64 i64 i64)))",
60            ),
61            (
62                "$memmove",
63                "(import \"env\" \"memmove\" (func $memmove (param i64 i64 i64)))",
64            ),
65            (
66                "$memset",
67                "(import \"env\" \"memset\" (func $memset (param i64 i64 i64)))",
68            ),
69        ]
70    }
71
72    /// Get the WASM type for MIR types (currently only i64).
73    pub fn get_wasm_type(&self, ty: &MirType) -> &'static str {
74        let _ = ty;
75        "i64"
76    }
77
78    /// Generate WASM local variable declaration.
79    pub fn generate_local_decl(&self, index: usize) -> String {
80        format!("    (local $l{index} i64)")
81    }
82}
83
84impl Abi for WasmABI {
85    fn target_os(&self) -> TargetOperatingSystem {
86        self.target_os
87    }
88
89    fn mangle_function_name(&self, name: &str) -> String {
90        WasmABI::mangle_function_name(self, name)
91    }
92}