nova-nix-0.6.0.0: src/Nix/Eval/CLambda.hs
-- | C-backed lambda closure structs via FFI.
--
-- Wraps @cbits/nn_lambda.c@ - a malloc'd struct holding the closure
-- environment (nn_env_t*), body bytecode index, and formal parameter
-- specification. Replaces StablePtr NixValue for VLambda (~25% of
-- remaining GHC heap after M6) with C-native tag 9 in the thunk system.
--
-- Lambda structs are tracked for bulk cleanup via 'clambdaFreeAll'
-- at evaluation end.
module Nix.Eval.CLambda
( -- * Opaque handle
NnLambda,
CLambdaPtr,
-- * Lifecycle
clambdaNew,
clambdaSetEntry,
clambdaFreeAll,
-- * Accessors
clambdaEnv,
clambdaBody,
clambdaFormalsType,
clambdaNameSym,
clambdaAllowExtra,
clambdaFormalCount,
clambdaEntryName,
clambdaEntryHasDefault,
clambdaEntryDefault,
)
where
import Data.Word (Word16, Word32, Word8)
import Foreign.Ptr (Ptr)
import Nix.Eval.CEnv (NnEnv)
-- | Phantom type for C-side @nn_lambda_t@.
data NnLambda
-- | Pointer to a C-allocated lambda closure.
type CLambdaPtr = Ptr NnLambda
-- ---------------------------------------------------------------------------
-- FFI imports (all unsafe - no callbacks, fast data access)
-- ---------------------------------------------------------------------------
foreign import ccall unsafe "nn_lambda_new"
c_nn_lambda_new :: Ptr NnEnv -> Word32 -> Word8 -> Word32 -> Word8 -> Word16 -> IO CLambdaPtr
foreign import ccall unsafe "nn_lambda_set_entry"
c_nn_lambda_set_entry :: CLambdaPtr -> Word16 -> Word32 -> Word32 -> Word32 -> IO ()
foreign import ccall unsafe "nn_lambda_free_all"
c_nn_lambda_free_all :: IO ()
foreign import ccall unsafe "nn_lambda_env"
c_nn_lambda_env :: CLambdaPtr -> IO (Ptr NnEnv)
foreign import ccall unsafe "nn_lambda_body"
c_nn_lambda_body :: CLambdaPtr -> IO Word32
foreign import ccall unsafe "nn_lambda_formals_type"
c_nn_lambda_formals_type :: CLambdaPtr -> IO Word8
foreign import ccall unsafe "nn_lambda_name_sym"
c_nn_lambda_name_sym :: CLambdaPtr -> IO Word32
foreign import ccall unsafe "nn_lambda_allow_extra"
c_nn_lambda_allow_extra :: CLambdaPtr -> IO Word8
foreign import ccall unsafe "nn_lambda_formal_count"
c_nn_lambda_formal_count :: CLambdaPtr -> IO Word16
foreign import ccall unsafe "nn_lambda_entry_name"
c_nn_lambda_entry_name :: CLambdaPtr -> Word16 -> IO Word32
foreign import ccall unsafe "nn_lambda_entry_has_default"
c_nn_lambda_entry_has_default :: CLambdaPtr -> Word16 -> IO Word32
foreign import ccall unsafe "nn_lambda_entry_default"
c_nn_lambda_entry_default :: CLambdaPtr -> Word16 -> IO Word32
-- ---------------------------------------------------------------------------
-- Lifecycle
-- ---------------------------------------------------------------------------
-- | Allocate a new lambda closure with space for @formalCount@ entries.
-- Fill entries via 'clambdaSetEntry' after construction.
clambdaNew :: Ptr NnEnv -> Word32 -> Word8 -> Word32 -> Word8 -> Word16 -> IO CLambdaPtr
clambdaNew = c_nn_lambda_new
-- | Set a formal entry at the given index.
clambdaSetEntry :: CLambdaPtr -> Word16 -> Word32 -> Word32 -> Word32 -> IO ()
clambdaSetEntry = c_nn_lambda_set_entry
-- | Free all tracked lambda structs (arena-style cleanup).
clambdaFreeAll :: IO ()
clambdaFreeAll = c_nn_lambda_free_all
-- ---------------------------------------------------------------------------
-- Accessors
-- ---------------------------------------------------------------------------
-- | Read the closure environment pointer.
clambdaEnv :: CLambdaPtr -> IO (Ptr NnEnv)
clambdaEnv = c_nn_lambda_env
-- | Read the body bytecode index.
clambdaBody :: CLambdaPtr -> IO Word32
clambdaBody = c_nn_lambda_body
-- | Read the formals type (0=Name, 1=Set, 2=NamedSet).
clambdaFormalsType :: CLambdaPtr -> IO Word8
clambdaFormalsType = c_nn_lambda_formals_type
-- | Read the binding name symbol (for Name/NamedSet).
clambdaNameSym :: CLambdaPtr -> IO Word32
clambdaNameSym = c_nn_lambda_name_sym
-- | Read the ellipsis flag (1 if ... present).
clambdaAllowExtra :: CLambdaPtr -> IO Word8
clambdaAllowExtra = c_nn_lambda_allow_extra
-- | Read the number of formal entries.
clambdaFormalCount :: CLambdaPtr -> IO Word16
clambdaFormalCount = c_nn_lambda_formal_count
-- | Read a formal entry's name symbol.
clambdaEntryName :: CLambdaPtr -> Word16 -> IO Word32
clambdaEntryName = c_nn_lambda_entry_name
-- | Read whether a formal entry has a default.
clambdaEntryHasDefault :: CLambdaPtr -> Word16 -> IO Word32
clambdaEntryHasDefault = c_nn_lambda_entry_has_default
-- | Read a formal entry's default bytecode index.
clambdaEntryDefault :: CLambdaPtr -> Word16 -> IO Word32
clambdaEntryDefault = c_nn_lambda_entry_default