libchat/nim-bindings
osmaczko 5767997e0e
fix(nim-bindings): bridge Nim/C ABI mismatch via C shim layer
Nim's code generator transforms function signatures involving large structs
in two ways that conflict with the standard C ABI:

  - Return values of large structs (> register size): Nim emits a void
    function with an explicit out-pointer appended as the *last* argument.
    The standard x86-64 SysV ABI passes the hidden return pointer in RDI
    (before the real arguments); ARM64 aapcs64 uses X8. Calling Rust
    directly from Nim therefore puts the pointer in the wrong register /
    stack slot on both architectures, causing crashes.

  - Large struct parameters (> ~24 bytes): Nim passes a pointer rather
    than copying bytes on the stack / into registers as the C ABI expects.

This commit introduces a thin C shim (nim_shims.c) that acts as a
translation layer:

  - Each nim_* wrapper is declared with a Nim-compatible signature, so
    Nim calls it correctly by its own rules.
  - Inside the wrapper the C compiler calls the real Rust-exported
    function using the standard C ABI, inserting the correct hidden-
    pointer placement and stack-copy behaviour for the current platform.

As a result:
  - The Rust API stays standard C ABI (return T by value; destroy takes
    *mut T, which is pointer-sized and matches Nim's large-param transform).
  - Other language bindings (C, Swift, Go, …) call Rust directly without
    any shim — the standard ABI is preserved for them.
  - The fix is correct on both x86-64 and ARM64 without any
    architecture-specific code in Nim or Rust.

Changes:
  - nim-bindings/src/nim_shims.c: C bridge with nim_* wrappers for all
    create/handle/installation_name and destroy functions
  - nim-bindings/src/bindings.nim: {.compile: "nim_shims.c"}, proc
    signatures use natural return-by-value form, importc names point to
    the nim_* shims
  - nim-bindings/src/libchat.nim: call sites use natural let binding form;
    destroy calls pass addr res (ptr T)
  - conversations/src/api.rs: destroy functions take *mut T so Nim's
    large-param-to-pointer transform is satisfied without a stack copy
2026-02-24 12:43:28 +01:00
..
2026-02-19 17:25:42 -08:00
2026-02-19 17:25:42 -08:00
2026-02-19 17:25:42 -08:00
2026-01-28 10:38:08 -08:00

Nim-bindings

A Nim wrapping class that exposes LibChat functionality.

Getting Started

nimble pingpong - Run the pingpong example.