|
9 | 9 | ||| All functions are declared here with type signatures and safety proofs. |
10 | 10 | ||| Implementations live in ffi/zig/ |
11 | 11 |
|
12 | | -module RpaElysium.ABI.Foreign |
| 12 | +module Foreign |
13 | 13 |
|
14 | | -import RpaElysium.ABI.Types |
15 | | -import RpaElysium.ABI.Layout |
| 14 | +import Types |
| 15 | +import Layout |
16 | 16 |
|
17 | 17 | %default total |
18 | 18 |
|
| 19 | +-------------------------------------------------------------------------------- |
| 20 | +-- FFI glue types (must match ffi/zig and the generated C header) |
| 21 | +-------------------------------------------------------------------------------- |
| 22 | + |
| 23 | +||| FFI result codes returned across the C ABI. Tag values MUST match the Zig |
| 24 | +||| implementation (ffi/zig): Ok=0, Error=1, InvalidParam=2, OutOfMemory=3, |
| 25 | +||| NullPointer=4. |
| 26 | +public export |
| 27 | +data Result : Type where |
| 28 | + Ok : Result |
| 29 | + Error : Result |
| 30 | + InvalidParam : Result |
| 31 | + OutOfMemory : Result |
| 32 | + NullPointer : Result |
| 33 | + |
| 34 | +public export |
| 35 | +Show Result where |
| 36 | + show Ok = "Ok" |
| 37 | + show Error = "Error" |
| 38 | + show InvalidParam = "InvalidParam" |
| 39 | + show OutOfMemory = "OutOfMemory" |
| 40 | + show NullPointer = "NullPointer" |
| 41 | + |
| 42 | +||| The C-ABI tag byte for a result code. |
| 43 | +public export |
| 44 | +resultTag : Result -> Bits32 |
| 45 | +resultTag Ok = 0 |
| 46 | +resultTag Error = 1 |
| 47 | +resultTag InvalidParam = 2 |
| 48 | +resultTag OutOfMemory = 3 |
| 49 | +resultTag NullPointer = 4 |
| 50 | + |
| 51 | +||| An opaque handle to a library instance, wrapping the raw C pointer as a |
| 52 | +||| Bits64. Constructed only via `createHandle`, which rejects the null pointer. |
| 53 | +public export |
| 54 | +data Handle : Type where |
| 55 | + MkHandle : Bits64 -> Handle |
| 56 | + |
| 57 | +||| Construct a handle from a raw pointer; `Nothing` for the null pointer. |
| 58 | +public export |
| 59 | +createHandle : Bits64 -> Maybe Handle |
| 60 | +createHandle 0 = Nothing |
| 61 | +createHandle p = Just (MkHandle p) |
| 62 | + |
| 63 | +||| The raw C pointer backing a handle. |
| 64 | +public export |
| 65 | +handlePtr : Handle -> Bits64 |
| 66 | +handlePtr (MkHandle p) = p |
| 67 | + |
19 | 68 | -------------------------------------------------------------------------------- |
20 | 69 | -- Library Lifecycle |
21 | 70 | -------------------------------------------------------------------------------- |
@@ -178,21 +227,25 @@ buildInfo = do |
178 | 227 | -- Callback Support |
179 | 228 | -------------------------------------------------------------------------------- |
180 | 229 |
|
181 | | -||| Callback function type (C ABI) |
| 230 | +||| Callback function type (C ABI) — the shape a registered callback must |
| 231 | +||| have: `(context : Bits64) -> (event : Bits32) -> (result : Bits32)`. |
182 | 232 | public export |
183 | 233 | Callback : Type |
184 | 234 | Callback = Bits64 -> Bits32 -> Bits32 |
185 | 235 |
|
186 | 236 | ||| Register a callback |
187 | 237 | export |
188 | 238 | %foreign "C:rpa_elysium_register_callback, librpa_elysium" |
189 | | -prim__registerCallback : Bits64 -> AnyPtr -> PrimIO Bits32 |
| 239 | +prim__registerCallback : Bits64 -> Bits64 -> PrimIO Bits32 |
190 | 240 |
|
191 | | -||| Safe callback registration |
| 241 | +||| Safe callback registration. The callback is passed as a raw pointer to a |
| 242 | +||| C-callable function of type `Callback`: an Idris closure cannot be handed to |
| 243 | +||| C directly (that needs a foreign export), so the caller supplies the |
| 244 | +||| already-C-callable function pointer (`cbPtr`). |
192 | 245 | export |
193 | | -registerCallback : Handle -> Callback -> IO (Either Result ()) |
194 | | -registerCallback h cb = do |
195 | | - result <- primIO (prim__registerCallback (handlePtr h) (cast cb)) |
| 246 | +registerCallback : Handle -> (cbPtr : Bits64) -> IO (Either Result ()) |
| 247 | +registerCallback h cbPtr = do |
| 248 | + result <- primIO (prim__registerCallback (handlePtr h) cbPtr) |
196 | 249 | pure $ case resultFromInt result of |
197 | 250 | Just Ok => Right () |
198 | 251 | Just err => Left err |
|
0 commit comments