Revised FFI syntax + typing

Sven Panne Sven.Panne at informatik.uni-muenchen.de
Tue May 1 15:31:09 EDT 2001


OK, after SPJ's mail and a few beers I'm now convinced that typing the
foreign construct is not as simple and orthogonal as I initially hoped.
After a close look into GHC's internals, H/Direct and Hugs I propose the
following in the hope that it's backwards compatible and not too confusing:

------------------------------------------------------------------------
Syntax for the 'foreign' language construct
------------------------------------------------------------------------

topdecl  : 'foreign' fkind modifier* var '::' type

-- even this could be merged into modifier somehow, but...  :-P
fkind    : 'import'
         | 'export'
         | 'label'

modifier : mode
         | callconv
         | safety
         | ext_ent

-- allowed for import/export
mode     : 'static'                  -- default
         | 'dynamic'

-- allowed for import/export
callconv : 'ccall'                   -- default
         | 'wincall'
         | 'stdcall'                 -- deprecated, same as wincall
         | 'cplusplus'
         | 'jvm'
         | 'dotnet'

-- allowed for import
safety   : 'safe'                    -- default
         | 'unsafe'

-- allowed for static import/export and label
ext_ent  : string                    -- default: the string rep. of var
         | string string             -- deprecated, first string ignored

------------------------------------------------------------------------
Types related to the FFI
------------------------------------------------------------------------

Note that data type renamings are completely "transparent", just like
type synonyms.

prim_type_i      : ['IO'] prim_result_i
                 | prim_arg_i '->' prim_type_i

prim_arg_i       : prim_arg
                 | foreign_ty
                 | unsafe_arr_ty     -- GHC extension
                 | unlifted_prim_ty  -- GHC extension

prim_result_i    : prim_result
                 | ['IO'] unlifted_prim_ty   -- GHC extension

prim_type        : ['IO'] prim_result
                 | prim_arg '->' prim_type

prim_result      : prim_arg
                 | '()'

prim_arg         : int_ty
                 | word_ty
                 | float_ty
                 | ptr_ty
                 | 'Bool'
                 | 'Char'
                 | 'StablePtr' a

int_ty           : 'Int'
                 | 'Int8'
                 | 'Int16'
                 | 'Int32'
                 | 'Int64'

word_ty          : 'Word8'
                 | 'Word16'
                 | 'Word32'
                 | 'Word64'
                 | 'Word'            -- GHC extension

float_ty         : 'Float'
                 | 'Double'

ptr_ty           : 'Addr'            -- deprecated
                 | 'Ptr' prim_result_i
                 | 'FunPtr' prim_type_i

-- arguments of this type are kept alive automagically across FFI calls.
foreign_ty       : 'ForeignObj'      -- deprecated
                 | 'ForeignPtr' prim_result

-- GHC extension, only in conjunction with 'unsafe' modifier
unsafe_arr_ty    : 'ByteArray' a
                 | 'MutableByteArray' i s a

-- GHC extension
unlifted_prim_ty : <any unlifted primary type>

------------------------------------------------------------------------
Typing rules for the ccall/wincall/stdcall calling convention
------------------------------------------------------------------------

Note that safety and ext_ent can be ignored for typing purposes, and that
prim_type{,_i}1 and prime_type{,_i}2 must be equal.

foreign import static  :: prim_type_i
foreign import dynamic :: 'FunPtr' prim_type_i1 '->' prim_type_i2
foreign export static  :: prim_type
foreign export dynamic :: prim_type1 -> 'IO' ('FunPtr' prim_type2)
foreign label          :: ptr_ty

Cheers,
   Sven




More information about the FFI mailing list