9 Commits

Author SHA1 Message Date
Ivan FB
1eb8f2bdf8
fix Hardcoded Nim build flags in generated build files. build.rs and CMakeLists.txt both bake in --mm:orc and -d:chronicles_log_level=WARN (rust.nim:121–122, cpp.nim:463–464).
The whole point of a generic generator is decoupling — this couples every consumer of nim-ffi to one specific project's Nim build conventions. Plumb these through
  genBindings() parameters or a config block.
2026-05-11 22:11:25 +02:00
Ivan FB
6920f22ab8
fix nlohmann namespace injection of optional adapters is ODR-fragile (cpp.nim:66–78). Every header that does this races every other header that does the same. In a small
project it's invisible; in something the size of nwaku's consumer surface i2t will eventually collide. Either gate behind a feature macro, or use nlohmann's adl_serializer
  specialization which is the documented extension point.
2026-05-11 21:52:00 +02:00
Ivan FB
7764b2f43b
fix C++ "async" methods spawn a thread per call that then blocks on a condvar (cpp.nim:362–377). std::async(std::launch::async, ...) forces a fresh thread, and the body runs
the blocking ffi_call_ which waits on a condvar with the user's timeout (default 30s). Under load this is a thread-explosion factory, and the name "async" is misleading — the
  Rust side has real async via tokio oneshot, but the C++ side has fake async. If true async isn't reachable in C++ without coroutines, fine, but at least pool the threads or
  document this is just a convenience wrapper.
2026-05-11 21:44:53 +02:00
Ivan FB
729801b999
Add ffiDtor concept 2026-05-10 11:38:43 +02:00
Ivan FB
af32a7bce8
Fix cpp vulnerabilities
1. No timeout → wait_for + 30 s default (ffi/codegen/cpp.nim)
ffi_call_ now takes std::chrono::milliseconds timeout and uses cv.wait_for. All factory/method signatures carry a timeout parameter (default std::chrono::seconds{30}), mirroring the Rust blocking API.

2. Stack-allocated state → shared_ptr ownership (ffi/codegen/cpp.nim)
ffi_cb_ now receives a heap-allocated std::shared_ptr<FfiCallState_>* as user_data. The refcount is 2 going in (one for ffi_call_, one for the callback). If ffi_call_ times out and returns, its copy drops — but the state stays alive (refcount 1) until Nim eventually calls back and delete sptr in ffi_cb_ drops the last reference. No more stack UAF.

3. Destructor + Rule of 5 (ffi/codegen/cpp.nim, examples/nim_timer/nim_timer.nim)

Added nimtimer_destroy to nim_timer.nim with {.dynlib, exportc, cdecl, raises: [].} — joins the FFI and watchdog threads, frees the context
Codegen now always emits void {libName}_destroy(void* ctx) in extern "C" and generates a destructor, deleted copy ctor/assignment, and move ctor/assignment for the context class
timeout_ stored in the class; move transfers it, destructor uses it
4. Hardcoded TimerConfig in createAsync (ffi/codegen/cpp.nim)
createAsync now uses the actual ctorParams list (same as create), so it's correct for any library, not just nim_timer.

5. Opaque exceptions → clear error messages (ffi/codegen/cpp.nim)
deserializeFfiResult wraps nlohmann::json::parse + .get<T>() in a catch that rethrows as "FFI response deserialization failed: ...". The stoull in create() is also try-caught with "FFI create returned non-numeric address: " + raw.
2026-05-10 11:38:42 +02:00
Ivan FB
798f5a21ed
simplify auto-generate cpp and rust 2026-05-10 11:38:42 +02:00
Ivan FB
bad1be30e6
enhance async cpp
Co-authored-by: Copilot <copilot@github.com>
2026-05-10 11:38:42 +02:00
Ivan FB
d87fe8b104
enhance cpp and rust tokio examples
Co-authored-by: Copilot <copilot@github.com>
2026-05-10 11:38:41 +02:00
Ivan FB
aa22b982be
allow auto-generate cpp code and add example 2026-05-10 11:38:41 +02:00