FFI with ABI instead of C declaration

Hi, all, I wonder: why, in Haskell and also in other languages like ML, FFI is done with C type and code as references? Since, ultimately, compiled code goes to, say, ELF files or (in Windows) DLLs, shouldn't foreign interfaces be consistent with those? I believe this could simplify writing foreign interfaces. Say, we could write something like this: foreign haskell_name1 binary_name1 :: T1 -> T2 -> IO T1 foreign haskell_name2 binary_name2 :: T1 -> T3 -> IO T4 Our FFI tool would take a set of binary libraries where to look for binary_name[i], and match haskell_name[i] with those. T[i] would be made synonyms of types which would offer all capabilities consistent with the corresponding types in those libraries ABIs. Inconsistency, of course, would be an error (like if, in the example above, the first parameter of both functions would not be the same). Thanks for your thoughts, Maurício

On March 11, 2011 09:17:54 Maurício CA wrote:
I wonder: why, in Haskell and also in other languages like ML, FFI is done with C type and code as references? Since, ultimately, compiled code goes to, say, ELF files or (in Windows) DLLs, shouldn't foreign interfaces be consistent with those?
Having an ELF file, a function name, and knowledge about the parameters for the function, is still not sufficient information to invoke it. I still need to know what calling convention is being used. That is, how to build the stack (which arguments to put on the stack and how to put them on), what to do with the registers (which arguments to put in them, which ones I can expect to be saved, any ones that are expected to be global pointers), how to receive results back (registers, on the stack, through a pointer), and, if I am expected to cleanup the stack afterwards. http://en.wikipedia.org/wiki/X86_calling_conventions Cheers! -Tyson

I wonder: why, in Haskell and also in other languages like ML, FFI is done with C type and code as references? Since, ultimately, compiled code goes to, say, ELF files or (in Windows) DLLs, shouldn't foreign interfaces be consistent with those?
Having an ELF file, a function name, and knowledge about the parameters for the function, is still not sufficient information to invoke it. I still need to know what calling convention is being used.
Is it possible to list the "set of sets" of suficient/consistent specifications one needs to list for each parameter for a function call? Types like those we have today (CInt, CSize, forall a. Ptr a etc.) are examples of such sets, but my naive guess is that we could have weaker ones. For instance, one doesn't need to know wheather a parameter is a pointer or an integer of the same size, as long as it's not actually used as a pointer, as opaque types sometimes do not identify themselves as pointers, and that doesn't prevent us from using them. Suppose we have C functions below. type_name give_me_opaque (void); void use_opaque (type_name); We could be able to say to Haskell (or other language) "foreign binder" that we have a type named MyOpaque and that: Properties of MyOpaque: may be copied. foreign import give_me_opaque :: IO MyOpaque foreign import use_opaque :: MyOpaque -> IO () MyOpaque would be assigned a type whose only property is to have a value (that you can copy and nothing else). The FFI tool would only have to verify (from a binary library header) that 'use_opaque' uses a parameter the same size of what 'give_me_opaque' returns. Other properties one could list for a type: be usable as an int32 (or int16, uint24 etc.), be usable as a pointer etc. A foreign function binding would have to list enough properties such that a set of suficient and consistent specifications could be obtained by crossing those properties with the information available in binary library headers. Does that make sense? Thanks for your toughts, Maurício
participants (2)
-
Maurício CA
-
Tyson Whitehead