use crate::mir_codegen::abi::Abi;
use lamina_platform::TargetOperatingSystem;
pub struct WasmABI {
target_os: TargetOperatingSystem,
}
impl WasmABI {
pub fn new(target_os: TargetOperatingSystem) -> Self {
Self { target_os }
}
pub fn mangle_function_name(&self, name: &str) -> String {
name.to_string()
}
pub fn get_print_import(&self) -> &'static str {
"(import \"console\" \"log\" (func $log (param i64)))"
}
pub fn get_wasm_type(&self, ty: &crate::mir::MirType) -> &'static str {
match ty {
crate::mir::MirType::Scalar(crate::mir::ScalarType::I64) => "i64",
_ => "i64",
}
}
pub fn generate_global_decl(&self, index: usize) -> String {
format!(" (global $vreg{} (mut i64) (i64.const 0))", index)
}
pub fn generate_local_decl(&self, index: usize) -> String {
format!(" (local $l{} i64)", index)
}
}
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)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_wasm_abi_new() {
let abi = WasmABI::new(TargetOperatingSystem::Linux);
assert_eq!(abi.target_os(), TargetOperatingSystem::Linux);
let abi_macos = WasmABI::new(TargetOperatingSystem::MacOS);
assert_eq!(abi_macos.target_os(), TargetOperatingSystem::MacOS);
}
#[test]
fn test_wasm_mangle_function_name() {
let abi = WasmABI::new(TargetOperatingSystem::Linux);
assert_eq!(abi.mangle_function_name("main"), "main");
assert_eq!(abi.mangle_function_name("foo"), "foo");
assert_eq!(abi.mangle_function_name("_main"), "_main");
let abi_macos = WasmABI::new(TargetOperatingSystem::MacOS);
assert_eq!(abi_macos.mangle_function_name("main"), "main");
assert_eq!(abi_macos.mangle_function_name("foo"), "foo");
}
#[test]
fn test_wasm_get_print_import() {
let abi = WasmABI::new(TargetOperatingSystem::Linux);
assert_eq!(
abi.get_print_import(),
"(import \"console\" \"log\" (func $log (param i64)))"
);
}
#[test]
fn test_wasm_get_wasm_type() {
use crate::mir::{MirType, ScalarType};
let abi = WasmABI::new(TargetOperatingSystem::Linux);
assert_eq!(abi.get_wasm_type(&MirType::Scalar(ScalarType::I64)), "i64");
assert_eq!(abi.get_wasm_type(&MirType::Scalar(ScalarType::I32)), "i64");
}
#[test]
fn test_wasm_generate_global_decl() {
let abi = WasmABI::new(TargetOperatingSystem::Linux);
assert_eq!(
abi.generate_global_decl(0),
" (global $vreg0 (mut i64) (i64.const 0))"
);
assert_eq!(
abi.generate_global_decl(42),
" (global $vreg42 (mut i64) (i64.const 0))"
);
}
#[test]
fn test_wasm_generate_local_decl() {
let abi = WasmABI::new(TargetOperatingSystem::Linux);
assert_eq!(abi.generate_local_decl(0), " (local $l0 i64)");
assert_eq!(abi.generate_local_decl(5), " (local $l5 i64)");
}
}