From 59e9f1fe20333cdf41ad269da020ac94dca5b6b4 Mon Sep 17 00:00:00 2001 From: Gabriel Cruz Date: Mon, 6 Jul 2026 10:57:53 -0300 Subject: [PATCH] fix: pr comments --- ffi/codegen/c.nim | 22 ++++++++++++++-------- ffi/codegen/rust.nim | 2 +- ffi/codegen/types_ir.nim | 10 +++++----- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/ffi/codegen/c.nim b/ffi/codegen/c.nim index 893e528..f841995 100644 --- a/ffi/codegen/c.nim +++ b/ffi/codegen/c.nim @@ -258,29 +258,33 @@ proc emitStructType(reg: var CTypeReg, t: FFITypeMeta) = proc ensureCType(reg: var CTypeReg, t: FFIType): tuple[cType: string, owns: bool] = ## Walks the shared type IR into a C type, monomorphising each distinct ## `seq[T]` / `Option[T]` into its own struct + codec triple on first sight. + ## `owns` marks a C type that carries heap-allocated payload the caller must + ## release with its generated free function (strings, byte buffers, and any + ## seq/opt/struct transitively containing one); plain scalars and pointers own + ## nothing and need no cleanup. case t.kind of ftPtr: - (CPtrType, false) + return (CPtrType, false) of ftScalar: - (scalarCInfoTable[t.scalar].cType, false) + return (scalarCInfoTable[t.scalar].cType, false) of ftStr: - ("NimFfiStr", true) + return ("NimFfiStr", true) of ftBytes: - ("NimFfiBytes", true) + return ("NimFfiBytes", true) of ftSeq: let (elemC, _) = ensureCType(reg, t.elem) let name = reg.libType & "Seq_" & cToken(elemC) if name notin reg.emitted: reg.emitted.incl(name) emitSeqType(reg, name, elemC) - (name, true) + return (name, true) of ftOpt: let (elemC, elemOwns) = ensureCType(reg, t.elem) let name = reg.libType & "Opt_" & cToken(elemC) if name notin reg.emitted: reg.emitted.incl(name) emitOptType(reg, name, elemC, elemOwns) - (name, reg.owns.getOrDefault(name, false)) + return (name, reg.owns.getOrDefault(name, false)) of ftStruct: let name = t.name if name notin reg.emitted: @@ -289,7 +293,7 @@ proc ensureCType(reg: var CTypeReg, t: FFIType): tuple[cType: string, owns: bool emitStructType(reg, reg.typeTable[name]) else: reg.decls.add("/* unknown type referenced: " & name & " */") - (name, reg.owns.getOrDefault(name, false)) + return (name, reg.owns.getOrDefault(name, false)) proc ensureCType(reg: var CTypeReg, nimType: string): tuple[cType: string, owns: bool] = ensureCType(reg, parseFFIType(nimType)) @@ -306,7 +310,9 @@ proc reqTypeMeta(p: FFIProcMeta): FFITypeMeta = func paramByValue(nimType: string, ridesAsPtr: bool): bool = ## Scalars / opaque pointers / string views pass by value; composite - ## aggregates (seq, Option, user structs) pass by const pointer. + ## aggregates (seq, Option, user structs) pass by const pointer. Note `ptr T` + ## rides by value as the 64-bit wire int (like `pointer`); production params + ## reach here as `pointer` since handles are pre-converted upstream. if ridesAsPtr: return true parseFFIType(nimType).kind in {ftScalar, ftStr, ftPtr} diff --git a/ffi/codegen/rust.nim b/ffi/codegen/rust.nim index 7c30b24..56544f3 100644 --- a/ffi/codegen/rust.nim +++ b/ffi/codegen/rust.nim @@ -1,7 +1,7 @@ ## Rust binding generator for the nim-ffi framework. ## Generates a complete Rust crate that uses CBOR (ciborium) on the wire. -import std/[os, strutils, sequtils] +import std/[os, strutils] import ./meta, ./string_helpers, ./types_ir ## Wire-format Rust type used for any Nim `ptr T` / `pointer`. Fixed 64-bit so diff --git a/ffi/codegen/types_ir.nim b/ffi/codegen/types_ir.nim index 30f8fdf..5771524 100644 --- a/ffi/codegen/types_ir.nim +++ b/ffi/codegen/types_ir.nim @@ -1,11 +1,11 @@ -## Structured type IR shared by the C / C++ / Rust binding generators: one +## Structured type model shared by the C / C++ / Rust binding generators: one ## parser (`parseFFIType`) for the Nim type strings each backend used to slice ## by hand, plus `renderNative` to walk the result into a backend's type string. import std/[strutils, options] type - ScalarKind* = enum + ScalarKind* {.pure.} = enum skBool skI8 skI16 @@ -18,7 +18,7 @@ type skF32 skF64 - FFITypeKind* = enum + FFITypeKind* {.pure.} = enum ftScalar ftStr ftBytes @@ -55,7 +55,7 @@ func genericInnerType(typeName, prefix: string): string = ## `genericInnerType("seq[int]", "seq[")` → `"int"`; "" if not that shape. if typeName.startsWith(prefix) and typeName.endsWith("]"): return typeName[prefix.len .. ^2] - "" + return "" func scalarKind(t: string): Option[ScalarKind] = ## Single source of truth for the scalar leaf set every backend shares. @@ -106,7 +106,7 @@ func parseFFIType*(typeName: string): FFIType = return FFIType(kind: ftOpt, elem: parseFFIType(optInner.strip())) let sc = scalarKind(t) - if sc.isSome: + if sc.isSome(): return FFIType(kind: ftScalar, scalar: sc.get()) if t == "string" or t == "cstring": return FFIType(kind: ftStr)