mirror of
https://github.com/logos-messaging/nim-ffi.git
synced 2026-01-02 14:13:10 +00:00
evolving more
This commit is contained in:
parent
86dc58e7c2
commit
da3251aa1a
5
ffi.nim
5
ffi.nim
@ -1,5 +1,8 @@
|
|||||||
|
import std/atomics, chronos
|
||||||
import
|
import
|
||||||
ffi/internal/[ffi_library, ffi_macro],
|
ffi/internal/[ffi_library, ffi_macro],
|
||||||
ffi/[alloc, ffi_types, ffi_context, ffi_thread_request]
|
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
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import std/[options, atomics, os, net, locks, json]
|
import std/[options, atomics, os, net, locks, json]
|
||||||
import chronicles, chronos, chronos/threadsync, taskpools/channels_spsc_single, results
|
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
|
type FFIContext*[T] = object
|
||||||
myLib*: T
|
myLib*: T
|
||||||
|
|||||||
@ -62,7 +62,7 @@ macro declareLibrary*(libraryName: static[string]): untyped =
|
|||||||
let nimMainName = ident("lib" & libraryName & "NimMain")
|
let nimMainName = ident("lib" & libraryName & "NimMain")
|
||||||
|
|
||||||
let initializeLibraryProc = quote:
|
let initializeLibraryProc = quote:
|
||||||
proc `procName`() {.exported.} =
|
proc `procName`*() {.exported.} =
|
||||||
if not initialized.exchange(true):
|
if not initialized.exchange(true):
|
||||||
## Every Nim library needs to call `<yourprefix>NimMain` once exactly,
|
## Every Nim library needs to call `<yourprefix>NimMain` once exactly,
|
||||||
## to initialize the Nim runtime.
|
## to initialize the Nim runtime.
|
||||||
@ -78,18 +78,4 @@ macro declareLibrary*(libraryName: static[string]): untyped =
|
|||||||
|
|
||||||
res.add(initializeLibraryProc)
|
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
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ proc extractFieldsFromLambda(body: NimNode): seq[NimNode] =
|
|||||||
var procNode = body
|
var procNode = body
|
||||||
if procNode.kind == nnkStmtList and procNode.len == 1:
|
if procNode.kind == nnkStmtList and procNode.len == 1:
|
||||||
procNode = procNode[0]
|
procNode = procNode[0]
|
||||||
if procNode.kind != nnkLambda:
|
if procNode.kind != nnkLambda and procNode.kind != nnkProcDef:
|
||||||
error "registerReqFFI expects a lambda proc, found: " & $procNode.kind
|
error "registerReqFFI expects a lambda proc, found: " & $procNode.kind
|
||||||
|
|
||||||
let params = procNode[3] # parameters list
|
let params = procNode[3] # parameters list
|
||||||
@ -24,7 +24,7 @@ proc buildRequestType(reqTypeName: NimNode, body: NimNode): NimNode =
|
|||||||
var procNode = body
|
var procNode = body
|
||||||
if procNode.kind == nnkStmtList and procNode.len == 1:
|
if procNode.kind == nnkStmtList and procNode.len == 1:
|
||||||
procNode = procNode[0]
|
procNode = procNode[0]
|
||||||
if procNode.kind != nnkLambda:
|
if procNode.kind != nnkLambda and procNode.kind != nnkProcDef:
|
||||||
error "registerReqFFI expects a lambda proc, found: " & $procNode.kind
|
error "registerReqFFI expects a lambda proc, found: " & $procNode.kind
|
||||||
|
|
||||||
let params = procNode[3] # formal params of the lambda
|
let params = procNode[3] # formal params of the lambda
|
||||||
@ -60,7 +60,7 @@ proc buildFfiNewReqProc(reqTypeName, body: NimNode): NimNode =
|
|||||||
else:
|
else:
|
||||||
procNode = body
|
procNode = body
|
||||||
|
|
||||||
if procNode.kind != nnkLambda:
|
if procNode.kind != nnkLambda and procNode.kind != nnkProcDef:
|
||||||
error "registerReqFFI expects a lambda definition. Found: " & $procNode.kind
|
error "registerReqFFI expects a lambda definition. Found: " & $procNode.kind
|
||||||
|
|
||||||
# T: typedesc[CreateNodeRequest]
|
# T: typedesc[CreateNodeRequest]
|
||||||
@ -186,7 +186,7 @@ proc buildProcessFFIRequestProc(reqTypeName, reqHandler, body: NimNode): NimNode
|
|||||||
var procNode = body
|
var procNode = body
|
||||||
if procNode.kind == nnkStmtList and procNode.len == 1:
|
if procNode.kind == nnkStmtList and procNode.len == 1:
|
||||||
procNode = procNode[0]
|
procNode = procNode[0]
|
||||||
if procNode.kind != nnkLambda:
|
if procNode.kind != nnkLambda and procNode.kind != nnkProcDef:
|
||||||
error "registerReqFFI expects a lambda definition. Found: " & $procNode.kind
|
error "registerReqFFI expects a lambda definition. Found: " & $procNode.kind
|
||||||
|
|
||||||
let typedescParam =
|
let typedescParam =
|
||||||
@ -362,6 +362,16 @@ macro ffi*(prc: untyped): untyped =
|
|||||||
for i in 1 ..< formalParams.len:
|
for i in 1 ..< formalParams.len:
|
||||||
newParams.add(newIdentDefs(formalParams[i][0], formalParams[i][1]))
|
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
|
# Build argument list for processReq
|
||||||
var argsList = newSeq[NimNode]()
|
var argsList = newSeq[NimNode]()
|
||||||
for i in 1 ..< formalParams.len:
|
for i in 1 ..< formalParams.len:
|
||||||
@ -394,12 +404,17 @@ macro ffi*(prc: untyped): untyped =
|
|||||||
pragmas = newTree(nnkPragma, ident "dynlib", ident "exportc"),
|
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
|
# registerReqFFI wrapper
|
||||||
let registerReq = quote:
|
let registerReq = quote:
|
||||||
registerReqFFI(`reqName`, `paramIdent`: `paramType`):
|
registerReqFFI(`reqName`, `paramIdent`: `paramType`):
|
||||||
proc(): Future[Result[string, string]] {.async.} =
|
`anonymousProcNode`
|
||||||
return `bodyNode`
|
|
||||||
|
|
||||||
# Final macro result
|
# Final macro result
|
||||||
result = newStmtList(registerReq, ffiProc)
|
result = newStmtList(registerReq, ffiProc)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user