packages feed

emacs-module-0.2: src/Data/Emacs/Module/Raw/Env/Internal.hs

----------------------------------------------------------------------------
-- |
-- 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