-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCallbacks.idr
More file actions
133 lines (116 loc) · 5.41 KB
/
Copy pathCallbacks.idr
File metadata and controls
133 lines (116 loc) · 5.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
-- SPDX-License-Identifier: MPL-2.0
-- Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
||| Safe Callback Types with Dependent Type Proofs
|||
||| This module defines the ABI-level callback type system for bidirectional
||| FFI communication. It provides type-safe callback registration with proofs
||| that:
||| 1. Callback handles are valid (non-zero)
||| 2. Event types are well-formed
||| 3. Callback invocation respects the registration contract
|||
||| This is the ABI layer (type definitions + proofs).
||| The FFI layer (actual C bindings) is in Proven.FFI.Callbacks.
module Proven.Callbacks
import Proven.Core
import Proven.FFI.Callbacks
%default total
--------------------------------------------------------------------------------
-- Validated Callback Handle
--------------------------------------------------------------------------------
||| A callback handle that has been validated as non-zero.
||| Constructed only through successful registration.
public export
data ValidHandle : Type where
MkValidHandle : (h : CallbackHandle) -> {auto prf : So (h /= 0)} -> ValidHandle
||| Extract the raw handle value.
public export
rawHandle : ValidHandle -> CallbackHandle
rawHandle (MkValidHandle h) = h
--------------------------------------------------------------------------------
-- Callback Registration Proof
--------------------------------------------------------------------------------
||| Evidence that a callback was successfully registered.
||| Carries the handle and the event type it was registered for.
public export
data Registered : EventType -> Type where
MkRegistered : (handle : ValidHandle) -> (eventType : EventType) -> Registered eventType
||| Get the handle from a registration proof.
public export
registeredHandle : Registered et -> ValidHandle
registeredHandle (MkRegistered h _) = h
||| Get the event type from a registration proof.
public export
registeredEventType : Registered et -> EventType
registeredEventType (MkRegistered _ et) = et
--------------------------------------------------------------------------------
-- Callback Safety Properties
--------------------------------------------------------------------------------
||| Property: event type round-trips through integer encoding.
public export
eventTypeRoundTrip : (et : EventType) -> intToEventType (eventTypeToInt et) = Just et
eventTypeRoundTrip ValidationFailed = Refl
eventTypeRoundTrip ResourceAcquired = Refl
eventTypeRoundTrip ResourceReleased = Refl
eventTypeRoundTrip RateLimitHit = Refl
eventTypeRoundTrip CircuitStateChange = Refl
eventTypeRoundTrip SignalReceived = Refl
eventTypeRoundTrip RetryAttempt = Refl
eventTypeRoundTrip CryptoOperation = Refl
eventTypeRoundTrip CustomEvent = Refl
||| Property: all event type integers are positive.
public export
eventTypePositive : (et : EventType) -> So (eventTypeToInt et > 0)
eventTypePositive ValidationFailed = Oh
eventTypePositive ResourceAcquired = Oh
eventTypePositive ResourceReleased = Oh
eventTypePositive RateLimitHit = Oh
eventTypePositive CircuitStateChange = Oh
eventTypePositive SignalReceived = Oh
eventTypePositive RetryAttempt = Oh
eventTypePositive CryptoOperation = Oh
eventTypePositive CustomEvent = Oh
--------------------------------------------------------------------------------
-- Safe Registration API
--------------------------------------------------------------------------------
||| Register a callback, returning a validated handle on success.
||| This is the safe wrapper around the FFI registration function.
||| Fails if the registry is full or the callback function is null.
export
registerCallback : EventType -> AnyPtr -> AnyPtr -> IO (Either CallbackError (Registered et))
registerCallback {et} eventType callbackFn context = do
h <- primIO $ prim__callbackRegister (eventTypeToInt eventType) callbackFn context
if h == 0
then pure (Left (RegistrationFailed "Registry full or null callback"))
else case choose (h /= 0) of
Left prf => pure (Right (MkRegistered (MkValidHandle h) eventType))
Right _ => pure (Left (RegistrationFailed "Unexpected zero handle"))
||| Unregister a callback using a validated handle.
export
unregisterCallback : ValidHandle -> IO (Either CallbackError ())
unregisterCallback vh = do
result <- primIO $ prim__callbackUnregister (rawHandle vh)
if result == 0
then pure (Right ())
else pure (Left (DeregistrationFailed ("Status: " ++ show result)))
--------------------------------------------------------------------------------
-- Scoped Callback (RAII-style)
--------------------------------------------------------------------------------
||| Run an IO action with a callback registered, automatically unregistering
||| the callback when the action completes. Ensures no leaked callbacks.
|||
||| @ eventType Event type to register for
||| @ callbackFn Function pointer (from host language)
||| @ context Opaque context pointer
||| @ action IO action to run while callback is active
export
withCallback : (eventType : EventType) -> (callbackFn : AnyPtr) -> (context : AnyPtr) ->
(action : IO a) -> IO (Either CallbackError a)
withCallback eventType callbackFn context action = do
regResult <- registerCallback eventType callbackFn context
case regResult of
Left err => pure (Left err)
Right reg => do
result <- action
_ <- unregisterCallback (registeredHandle reg)
pure (Right result)