| ... | ... | @@ -3,6 +3,17 @@ |
|
|
|
|
|
|
|
One is forced to use an external C file to allocate data in the bss or data segment even though no code at all will be output and the object file will simply contain a linker directive to allocate some space. This is a deficiency in the current FFI spec.
|
|
|
|
|
|
|
|
|
|
|
|
This is very easy to implement and is needed for low level haskell programming or when you wish to replace certain aspects of a haskell runtime with haskell code itself. It is currently the only thing one cannot do at all in haskell that one can do in C.
|
|
|
|
|
|
|
|
|
|
|
|
In addition to low level programming, any program that uses large amounts of static (or preallocated) data can benefit due to
|
|
|
|
|
|
|
|
- decreased binary size
|
|
|
|
- faster start up times
|
|
|
|
- less memory consumption
|
|
|
|
- constant data being shared among multiple running copies of the same program
|
|
|
|
|
|
|
|
## Proposal (experimental in jhc)
|
|
|
|
|
|
|
|
|
| ... | ... | @@ -22,12 +33,12 @@ the space allocated will be n\*sizeof type for the sizeof as specified by the St |
|
|
|
if the type is 'forall a . Ptr a' then the size will be assumed to be one byte.
|
|
|
|
|
|
|
|
|
|
|
|
if 'const' is specified then that is an assertion the contents of memory there will never change and the haskell compiler may make use of that and the data may be allocated in the shared among processes, read-only data segment.
|
|
|
|
if 'const' is specified then that is an assertion the contents of memory there will never be modaified. It is a strong assertion in that the compiler is free to perform optimizations that rely on that fact, and place that memory in a segment that is unwritable and shared among processes.
|
|
|
|
|
|
|
|
### initialized data
|
|
|
|
|
|
|
|
|
|
|
|
initialized data is trickier, a possible syntax is
|
|
|
|
The initial contents of the memory may also be specified:
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
foreign space [bigendian|littleendian] [const] <n> :: Ptr <type> = constant
|
| ... | ... | @@ -56,25 +67,4 @@ Implementation is trivial once you can parse the new constructs (purposfully sim |
|
|
|
## caveats
|
|
|
|
|
|
|
|
|
|
|
|
It is anoying that \<n\> must be a constant and \<type\> must be a builtin, but there is not really any other recourse without defining a preprocessor in haskell or a staged system like template haskell. however, use of CPP or a preprocessor like hsc2hs will mitigate these problems and the situation is no worse (and somewhat better) than when having to link against an external C library.
|
|
|
|
|
|
|
|
|
|
|
|
A possible extension would be to allow implementations to derive instances of Storable and allow types with such derived instances be used in foreign space declarations too.
|
|
|
|
|
|
|
|
|
|
|
|
another possibility is the definition of 'manifestly constant' data. which is defined as declarations of the form
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
name :: built-in-type
|
|
|
|
name = <constant>
|
|
|
|
```
|
|
|
|
|
|
|
|
- or sizeof a builtin
|
|
|
|
|
|
|
|
- or 'foo \<op\> bar' where foo and bar are manifestly constant and op is a basic operation.
|
|
|
|
|
|
|
|
|
|
|
|
then allow such manifestly constant values for n and allow types whose sizeof is manifestly constant to be used in foreign space declarations.
|
|
|
|
|
|
|
|
|
|
|
|
however, this is probably a lot of work for a problem that has better workarounds unless other uses for manifestly constant data are found. |
|
|
|
It is anoying that \<n\> must be a constant and \<type\> must be a builtin, but there is not really any other recourse without defining a preprocessor in haskell and the restrictions are no more onerous than those placed on the arguments to foreign function calls. Something like template haskell would mitigate this problem when available. |