Lines
100 %
Functions
40 %
Branches
//! Host-fn import registration + lookup.
//!
//! Each entry in the rpc `HostFnSpec` registry gets wired up here:
//! the wasm import is declared with the spec's param/result types
//! (collapsed to abstract heap-types for GC-ref kinds), and a
//! lookup-table entry records the function index plus the original
//! `WasmType` signature for the compiler's call-site emit.
use super::{CompileContext, HostFnEntry};
use crate::error::Result;
use crate::host_fn::HostFnSpec;
use wasm_encoder::ValType;
impl CompileContext {
pub(super) fn register_host_fn(&mut self, spec: &HostFnSpec) -> Result<()> {
// Args ride the wasm function signature directly. Each declared
// param type maps to its abstract `WasmTy::valtype()` (`(ref null
// struct)` for Commodity / Ratio / Pair / EntityRef, `(ref null
// array)` for StringRef, primitive types unchanged); host fn body
// reads them as closure args. The earlier capture-queue path
// retired in P4 A6.b.
let params: Vec<ValType> = spec
.params
.iter()
.map(|t| self.host_import_return_type(*t))
.collect();
// Result signature is driven by `spec.result` alone. Host fns
// returning typed GC refs (Ratio / Commodity / StringRef / Pair)
// report their wasm signature via `WasmTy::valtype()` as the
// abstract heap type (`(ref null struct)` / `(ref null array)`)
// — the import declaration matches, and the guest follows the
// call with a `ref.cast` to recover the concrete type. See
// `host_import_return_type` for the mapping.
let results: Vec<ValType> = spec
.result
let func_idx =
self.register_import(&spec.import_module, &spec.import_name, ¶ms, &results)?;
self.host_fns.insert(
spec.nomi_name.clone(),
HostFnEntry {
func_idx,
params: spec.params.clone(),
result: spec.result,
},
);
Ok(())
}
pub(crate) fn lookup_host_fn(&self, name: &str) -> Option<&HostFnEntry> {
self.host_fns.get(name)