Proposal #2: marshalling utilites

Manuel M. T. Chakravarty chak at cse.unsw.edu.au
Fri Dec 1 21:49:52 EST 2000


Simon Marlow <simonmar at microsoft.com> wrote,

> The main concern as far as adding functionality to the marshalling
> libraries seems to be the need to separate the compiler-dependent
> primitives from the rest of the library.  With that in mind, I'll
> propose the following changes:
> 
> 	* Deprecate everything in Storable except the class itself 
> 	  and its instances.
> 
>       * Add the Marshal module below (the names are of course all
>         up for discussion, including the name of the module itself).
> 
> The implementation of Marshal is compiler independent, except there's a
> requirement for a way to convert an errno value into an IOError.  As
> noted below, perhaps the error processing, or at least the
> compiler-dependent portion, should be farmed off into another module.
> 
> I omitted some of the generic utilities from Marcin's proposal, since
> while obviously useful they don't seem to belong here.
>  
> ------------------------------------------------------------------------
>     -- Allocation, deallocation and marshalling for objects and arrays
> 
>     malloc,       -- :: Storable a =>        IO (Ptr a)
>     mallocArray,  -- :: Storable a => Int -> IO (Ptr a)
>     mallocBytes,  -- ::               Int -> IO (Ptr a)
> 
>     alloca,       -- :: Storable a =>        (Ptr a -> IO b) -> IO b
>     allocaArray,  -- :: Storable a => Int -> (Ptr a -> IO b) -> IO b
>     allocaBytes,  -- ::               Int -> (Ptr a -> IO b) -> IO b
> 
>     reallocArray, -- :: Storable a => Ptr a -> Int -> IO (Ptr a)
>     reallocBytes, -- ::               Ptr a -> Int -> IO (Ptr a)
> 
>     free          -- :: Ptr a -> IO ()
> 
>     pokeArray,  	-- :: Storable a => Ptr a -> [a] -> IO ()
>     pokeArray0, 	-- :: Storable a => a -> Ptr a -> [a] -> IO ()
> 
>     peekArray,  	-- :: Storable a => Ptr a -> Int -> IO [a]
>     peekArray0, 	-- :: (Storable a, Eq a) => a -> Ptr a -> IO [a]
> 
>     withObject,	-- :: Storable a => a -> (Ptr a -> IO b) -> IO b
>     withArray, 	-- :: Storable a => [a] -> (Ptr a -> IO b) -> IO b
>     withArray0,	-- :: Storable a => a -> [a] -> (Ptr a -> IO b) -> IO b
> 
>     new,		-- :: Storable a => a -> IO (Ptr a)
>     newArray, 	-- :: Storable a => [a] -> IO (Ptr a)
>     newArray0,	-- :: Storable a => a -> [a] -> IO (Ptr a)
> 
>     ----------------------------------------------------------------
>     -- Haskellish interface to memcpy and memmove.
> 
>     copyArray,	-- :: Storable a => Ptr a -> Ptr a -> Int -> IO ()
>     copyBytes,	-- :: Ptr a -> Ptr a -> Int -> IO ()
> 
>     moveArray,	-- :: Storable a => Ptr a -> Ptr a -> Int -> IO ()
>     moveBytes,	-- :: Ptr a -> Ptr a -> Int -> IO ()
> 
[..]
> ------------------------------------------------------------------------
> -----
>    -- Misc
>    indexPtr     -- :: Storable a => Ptr a -> Int -> Ptr a
>  )

These are fine with me.

>    ------------------------------------------------------------------
>    -- Error handling.
> 
>    -- Perhaps these should be moved to another module (PosixError?)
> 
>    getErrno,		-- :: IO Int
>    throwIf,			-- :: (a -> Bool) -> String -> IO a ->
> IO a
>    throwIf_EINTR, 	-- :: (a -> Bool) -> String -> IO a -> IO a
>    throwIfNull, 		-- :: String -> IO (Ptr a) -> IO (Ptr a)
>    throwIfNull_EINTR,  	-- :: String -> IO (Ptr a) -> IO (Ptr a)
>    throwIfMinus1,		-- :: Num a => String -> IO a -> IO a
>    throwIfMinus1_EINTR,	-- :: Num a => String -> IO a -> IO a
>    throwCError, 		-- :: String -> Int -> IO a
>    throwErrno,  		-- :: String -> IO a

IMHO, they should go into another module.  `PosixError'
seems reasonable.  

Moreover, the first set of functions should be re-exported
by `Foreign' (which re-exports all the language independent
low-level FFI).  Not so, PosixError, which isn't part of
`Foreign' (like CTypes isn't).

And because the greatest fun of all is to argue about names,
I propose to rename `throwIf_EINTR', `throwIfNull_EINTR',
and `throwIfMinus1_EINTR' to `throwIfEINTR',
`throwIfNullEINTR', and `throwIfMinus1EINTR', respectively.

For GHC, we should specify Qrczak's requirement that errno
is thread local.

Finally, I am not sure whether we should really call the
module `Marshal', because that would have been the name that
I would have given the main interface to the higher-level
marshalling module.  How about `MarshalUtils' (following the
subject of this thread)?

Cheers,
Manuel




More information about the FFI mailing list