From da3251aa1a3c4c939d5602b31c75aa60ac269880 Mon Sep 17 00:00:00 2001 From: Ivan Folgueira Bande Date: Wed, 10 Dec 2025 17:43:26 +0100 Subject: [PATCH] evolving more --- ffi.nim | 5 ++++- ffi/ffi_context.nim | 2 +- ffi/internal/ffi_library.nim | 16 +--------------- ffi/internal/ffi_macro.nim | 29 ++++++++++++++++++++++------- 4 files changed, 28 insertions(+), 24 deletions(-) diff --git a/ffi.nim b/ffi.nim index ce1c7ec..ed14bad 100644 --- a/ffi.nim +++ b/ffi.nim @@ -1,5 +1,8 @@ +import std/atomics, chronos import ffi/internal/[ffi_library, ffi_macro], ffi/[alloc, ffi_types, ffi_context, ffi_thread_request] -export alloc, ffi_library, ffi_macro, ffi_types, ffi_context, ffi_thread_request +export atomics, chronos +export + atomics, alloc, ffi_library, ffi_macro, ffi_types, ffi_context, ffi_thread_request diff --git a/ffi/ffi_context.nim b/ffi/ffi_context.nim index 89549d0..4b692f9 100644 --- a/ffi/ffi_context.nim +++ b/ffi/ffi_context.nim @@ -4,7 +4,7 @@ import std/[options, atomics, os, net, locks, json] import chronicles, chronos, chronos/threadsync, taskpools/channels_spsc_single, results -import ./ffi_types, ./ffi_thread_request, ./ffi_watchdog_req, ./internal/ffi_macro +import ./ffi_types, ./ffi_thread_request, ./internal/ffi_macro type FFIContext*[T] = object myLib*: T diff --git a/ffi/internal/ffi_library.nim b/ffi/internal/ffi_library.nim index 9df1cc3..3f1b757 100644 --- a/ffi/internal/ffi_library.nim +++ b/ffi/internal/ffi_library.nim @@ -62,7 +62,7 @@ macro declareLibrary*(libraryName: static[string]): untyped = let nimMainName = ident("lib" & libraryName & "NimMain") let initializeLibraryProc = quote: - proc `procName`() {.exported.} = + proc `procName`*() {.exported.} = if not initialized.exchange(true): ## Every Nim library needs to call `NimMain` once exactly, ## to initialize the Nim runtime. @@ -78,18 +78,4 @@ macro declareLibrary*(libraryName: static[string]): untyped = res.add(initializeLibraryProc) - ## Generate the exported C-callable callback setter - let setCallbackProc = quote: - proc set_event_callback( - ctx: ptr FFIContext, callback: FFICallBack, userData: pointer - ) {.dynlib, exportc.} = - initializeLibrary() - ctx[].eventCallback = cast[pointer](callback) - ctx[].eventUserData = userData - - res.add(setCallbackProc) - - # echo result.repr return res - - diff --git a/ffi/internal/ffi_macro.nim b/ffi/internal/ffi_macro.nim index 4dafa81..33f7dd3 100644 --- a/ffi/internal/ffi_macro.nim +++ b/ffi/internal/ffi_macro.nim @@ -7,7 +7,7 @@ proc extractFieldsFromLambda(body: NimNode): seq[NimNode] = var procNode = body if procNode.kind == nnkStmtList and procNode.len == 1: procNode = procNode[0] - if procNode.kind != nnkLambda: + if procNode.kind != nnkLambda and procNode.kind != nnkProcDef: error "registerReqFFI expects a lambda proc, found: " & $procNode.kind let params = procNode[3] # parameters list @@ -24,7 +24,7 @@ proc buildRequestType(reqTypeName: NimNode, body: NimNode): NimNode = var procNode = body if procNode.kind == nnkStmtList and procNode.len == 1: procNode = procNode[0] - if procNode.kind != nnkLambda: + if procNode.kind != nnkLambda and procNode.kind != nnkProcDef: error "registerReqFFI expects a lambda proc, found: " & $procNode.kind let params = procNode[3] # formal params of the lambda @@ -60,7 +60,7 @@ proc buildFfiNewReqProc(reqTypeName, body: NimNode): NimNode = else: procNode = body - if procNode.kind != nnkLambda: + if procNode.kind != nnkLambda and procNode.kind != nnkProcDef: error "registerReqFFI expects a lambda definition. Found: " & $procNode.kind # T: typedesc[CreateNodeRequest] @@ -186,7 +186,7 @@ proc buildProcessFFIRequestProc(reqTypeName, reqHandler, body: NimNode): NimNode var procNode = body if procNode.kind == nnkStmtList and procNode.len == 1: procNode = procNode[0] - if procNode.kind != nnkLambda: + if procNode.kind != nnkLambda and procNode.kind != nnkProcDef: error "registerReqFFI expects a lambda definition. Found: " & $procNode.kind let typedescParam = @@ -362,6 +362,16 @@ macro ffi*(prc: untyped): untyped = for i in 1 ..< formalParams.len: newParams.add(newIdentDefs(formalParams[i][0], formalParams[i][1])) + # Build Future[Result[string, string]] return type + let futReturnType = quote: + Future[Result[string, string]] + + var userParams = newSeq[NimNode]() + userParams.add(futReturnType) + if formalParams.len > 3: + for i in 4 ..< formalParams.len: + userParams.add(newIdentDefs(formalParams[i][0], formalParams[i][1])) + # Build argument list for processReq var argsList = newSeq[NimNode]() for i in 1 ..< formalParams.len: @@ -394,12 +404,17 @@ macro ffi*(prc: untyped): untyped = pragmas = newTree(nnkPragma, ident "dynlib", ident "exportc"), ) + var anonymousProcNode = newProc( + name = newEmptyNode(), # anonymous proc + params = userParams, + body = newStmtList(bodyNode), + pragmas = newTree(nnkPragma, ident"async"), + ) + # registerReqFFI wrapper let registerReq = quote: registerReqFFI(`reqName`, `paramIdent`: `paramType`): - proc(): Future[Result[string, string]] {.async.} = - return `bodyNode` + `anonymousProcNode` # Final macro result result = newStmtList(registerReq, ffiProc) -