"token" was overloaded (auth tokens, cgo handles, lexer tokens) and didn't say
what it is — a per-call correlation id linking an outgoing {.ffiHost.} call to
the answer that arrives later (possibly from another thread). Renamed across the
runtime (ffi_host / ffi_context), the macro, the exported C ABI (FFIHostFn,
<lib>_host_complete), the Go trampoline, and the tests; regenerated bindings.
The unrelated request-path cgo.Handle result-slot (also informally called a
"token" in go.nim comments) is left as-is — different mechanism.
16 host unit tests + the examples/host_demo Go round-trip stay green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
5a: record {.ffiHost.} procs in a compile-time registry (FFIHostMeta /
ffiHostRegistry), populated by the macro, so generators can see host fns.
5b: the Go generator emits an idiomatic wrapper over the host C ABI:
- a single //export cgo trampoline backs every host fn; a cgo.Handle in
userData selects the Go closure;
- the closure runs on a fresh GOROUTINE so the FFI thread is never blocked
(the non-blocking contract), then answers via <lib>_host_complete by token;
- a per-host `Set<Name>(func(string) (string, error))` method registers it.
Validated end to end with `go run` (examples/host_demo): Go UseToken -> Nim
{.ffi.} handler -> await fetchToken {.ffiHost.} -> Go trampoline -> goroutine
runs the closure -> host_complete -> future resolves on the loop thread ->
"token[TOK-session]" back in Go. Timer's Go output is unchanged (no host fns);
its regenerated .h just gains the always-exported host ABI decls.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>