You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A loaded .so can't be asked "what's your API?" at runtime. generateCddlSchema/generateCddlBindings (ffi/codegen/cddl.nim) already produce a complete CDDL document from ffiProcRegistry/ffiTypeRegistry (per-type rules, per-proc request envelopes, request/response rules), but it's only emitted to a file at codegen time (genbindings_cddl). Nothing surfaces it at runtime.
Proposal
The CDDL string is fully determined by the compile-time registries, so it can be baked into the library as a const and returned through a C export.
6a — bake the schema as a const. At genBindings() time (runs in the library's own compilation), emit const ffiSchemaCddl* = "..." and const ffiSchemaCbor* = [...] (a CBOR descriptor: {lib, version, requests:[{name, reqFields, respFields}], events:[{wireName, payloadFields}], abi}). Factor the registry→descriptor step out of generateCddlSchema so the file emitter and the const emitter share it; add a CBOR renderer.
6b — C exports (static, borrowed, callable before create):
constchar*<lib>_get_schema_cddl(void); // NUL-terminated, never freedvoid<lib>_get_schema_cbor(constuint8_t**out, size_t*outLen);
uint64_t<lib>_schema_version(void); // stable hash for ABI-mismatch detection
schema_version = a deterministic hash over sorted proc/type names + field types.
6c — wrapper surface. Thin schema()/getSchema() accessor per wrapper (rust/cpp/python/go) returning the string/parsed descriptor. Cheap once the C export exists.
Gotchas
The descriptor must reflect the runtime ABI mode — if the C-wire ABI lands (Minor: Fixed indentation #2), include a per-proc abi field (wire FFIProcMeta.abiFormat, already present).
Keep it borrowed/static — no per-call alloc, no ownership API for a read-only constant.
Hash stability: CBOR maps are keyed, so sort before hashing; don't include field order unless order is part of the wire contract.
Tests
Load the built timer lib; assert get_schema_cddl() equals the checked-in examples/timer/cddl_bindings/my_timer.cddl (ties into check_bindings).
Round-trip: parse get_schema_cbor(), assert it lists every {.ffi.} proc/event in the example.
schema_version stability: identical source → identical hash across builds and orc/refc.
Effort: small-medium. The registry walk already exists in cddl.nim; mostly "render to a const + add three trivial C exports."
Problem
A loaded
.socan't be asked "what's your API?" at runtime.generateCddlSchema/generateCddlBindings(ffi/codegen/cddl.nim) already produce a complete CDDL document fromffiProcRegistry/ffiTypeRegistry(per-type rules, per-proc request envelopes, request/response rules), but it's only emitted to a file at codegen time (genbindings_cddl). Nothing surfaces it at runtime.Proposal
The CDDL string is fully determined by the compile-time registries, so it can be baked into the library as a
constand returned through a C export.6a — bake the schema as a const. At
genBindings()time (runs in the library's own compilation), emitconst ffiSchemaCddl* = "..."andconst ffiSchemaCbor* = [...](a CBOR descriptor:{lib, version, requests:[{name, reqFields, respFields}], events:[{wireName, payloadFields}], abi}). Factor the registry→descriptor step out ofgenerateCddlSchemaso the file emitter and the const emitter share it; add a CBOR renderer.6b — C exports (static, borrowed, callable before
create):schema_version= a deterministic hash over sorted proc/type names + field types.6c — wrapper surface. Thin
schema()/getSchema()accessor per wrapper (rust/cpp/python/go) returning the string/parsed descriptor. Cheap once the C export exists.Gotchas
abifield (wireFFIProcMeta.abiFormat, already present).Tests
get_schema_cddl()equals the checked-inexamples/timer/cddl_bindings/my_timer.cddl(ties intocheck_bindings).get_schema_cbor(), assert it lists every{.ffi.}proc/event in the example.schema_versionstability: identical source → identical hash across builds and orc/refc.Effort: small-medium. The registry walk already exists in
cddl.nim; mostly "render to a const + add three trivial C exports."