---------------------------------------------------------------------------- -- | -- Module : Data.Emacs.Module.Env.Internal -- Copyright : (c) Sergey Vinokurov 2018 -- License : Apache-2.0 (see LICENSE) -- Maintainer : serg.foo@gmail.com ---------------------------------------------------------------------------- {-# LANGUAGE DataKinds #-} {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE UnliftedFFITypes #-} {-# LANGUAGE UnliftedNewtypes #-} {-# OPTIONS_HADDOCK not-home #-} module Data.Emacs.Module.Raw.Env.Internal ( Env(..) , Environment , toPtr , fromPtr , exportToEmacs , RawFunctionType , RawFunction(..) , freeHaskellFunPtrWrapped ) where import Foreign import Foreign.C.Types import GHC.Exts (Addr#, Ptr(..)) import Data.Emacs.Module.Raw.Value.Internal -- | Emacs environment, right from the 'emacs-module.h'. newtype Env = Env { unEnv# :: Addr# } data Environment {-# INLINE toPtr #-} toPtr :: Env -> Ptr Environment toPtr (Env x) = Ptr x {-# INLINE fromPtr #-} fromPtr :: Ptr Environment -> Env fromPtr (Ptr x) = Env x type RawFunctionType o a = Ptr Environment -> CPtrdiff -- Number of arguments -> Ptr (RawValue 'Regular) -- Actual arguments, always supplied by Emacs so never 'Pinned'. -> Ptr a -- Extra data -> IO (RawValue o) -- NB This is *the* coolest point of this library: *any* Haskell -- function (incl closures) may be exposed to C to be called later. -- The C/C++ will never have this... -- | Take Haskell function and return C pointer to function (which -- ideally needs to be cleaned up later by 'freeHaskellFunPtrWrapped'). foreign import ccall "wrapper" exportToEmacs :: RawFunctionType o a -> IO (RawFunction o a) -- | Pointer to a function that may later be called by by Emacs. newtype RawFunction o a = RawFunction { unRawFunction :: FunPtr (RawFunctionType o a) } deriving (Eq, Ord, Show) -- This function is defined in base. See what 'freeHaskellFunPtr' for a start. foreign import ccall unsafe "&freeHaskellFunctionPtr" freeHaskellFunPtrWrapped :: FinalizerPtr a