Added
- Host Extension API (
prd-host-extension-api.mdPhases 1–3), behind
the newCEDAR_HOST_EXTENSIONSCMake option — default OFF, so the
WASM/web build, the CLI and every existing program are untouched.
Embedders can register, once at init:akkado::register_host_variable(...)— control-rate host signals,
desugared onto the existingbpm/srENV_GETpath. Drive them via
vm.set_param(akkado::host_variable_env_key("name"), x).akkado::register_host_function(...)— with a nullimpl_fnit
aliases an existing core opcode; with animpl_fnit becomes a real
host opcode.akkado::register_host_node(...)— a stateful node naming a
heavyweight host-owned instance (nkido studio'splugin("Diva")).
Codegen records each call site inCompileResult::required_host_nodes
so the host can bind a pooled instance to thatstate_idoff the
audio thread. The engine never loads, prepares or destroys the
instance, and needs no lifecycle hooks.
HOST_OPopcode (209) dispatched throughcedar::HostOpRegistry,
a 256-entry table indexed byinst.rate. Host extensibility costs one
enum slot regardless of how many host ops are registered; core opcodes
keep their jump table and only host ops pay one indirect call.HostOpState— arena-backed per-instance host-op state with a
release()hook, so the existingHasArenaReleaseStatePool sweep
reclaims it. No per-region arena free had to be added.
Name collisions with a core builtin, alias, or variable — or with an
earlier host registration — are rejected, never shadowed. Audio-rate host
variables and hosted-node event-stream inputs are likewise rejected
rather than silently ignored; both land with Phase 4 and the studio's
plugin backend respectively.
Nondestructiveness verified: full cedar + akkado suites pass with the flag
both ON and OFF, registering a host op leaves an unrelated program's
bytecode byte-identical, and three fixtures rendered 300 s each produce
bit-identical WAVs from ON and OFF builds.