Lines
100 %
Functions
20 %
Branches
//! Per-`(defun_name, signature)` monomorph cache.
//!
//! Tier 1.5 closes Gap B (recursive defun called with a runtime arg) by
//! lowering through a real wasm fn rather than the inline const-fold
//! walk. Each distinct call-site signature gets its own emitted fn:
//! `(defun fact (n) ...)` called with a `Ratio` arg emits one wasm fn,
//! the same defun called with (hypothetically) a `Commodity` arg emits
//! another. The cache lookup is keyed by `(name, params)` so call sites
//! with identical signatures share one fn — including the recursive
//! self-call inside the body.
//! The cache is mutated only by [`CompileContext::lookup_or_emit_monomorph`]
//! (added in `compiler/expr/call.rs`) and snapshot-restored along with
//! the rest of the wasm-section state via [`super::snapshot`].
use std::collections::HashMap;
use crate::ast::WasmType;
use super::CompileContext;
/// One monomorph entry: the wasm fn idx at which the body was emitted
/// plus the body-derived return type. Cloneable + Eq because it lives
/// in the snapshot/restore graph.
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct MonomorphEntry {
pub func_idx: u32,
pub ret_ty: WasmType,
}
/// Cache key: defun name + monomorph parameter signature. The body
/// AST stays stored on the `Symbol::function` slot — re-fetched at
/// emit time rather than duplicated here, so renaming or redefining a
/// defun invalidates the cache implicitly via lookup.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub(crate) struct MonomorphKey {
pub name: String,
pub params: Vec<WasmType>,
#[derive(Debug, Default, Clone)]
pub(crate) struct MonomorphCache {
entries: HashMap<MonomorphKey, MonomorphEntry>,
impl MonomorphCache {
pub(crate) fn get(&self, key: &MonomorphKey) -> Option<&MonomorphEntry> {
self.entries.get(key)
pub(crate) fn insert(&mut self, key: MonomorphKey, entry: MonomorphEntry) {
self.entries.insert(key, entry);
impl CompileContext {
pub(crate) fn monomorph_cache(&self) -> &MonomorphCache {
&self.monomorphs
pub(crate) fn monomorph_cache_mut(&mut self) -> &mut MonomorphCache {
&mut self.monomorphs