FFI Definition
Sven Panne
Sven.Panne at informatik.uni-muenchen.de
Tue May 1 06:19:36 EDT 2001
A few comments on this FFI spec:
* `foreign label' is missing, but that has already been pointed
out. But I'm not sure how this should interact with the different
calling conventions, e.g. what should the address of a Java method
mean?
* I'm not very happy with the fact that static/dynamic are only viewed
as modifiers, like unsafe/safe. They almost completely change the
meaning of a foreign declaration, including the typing rules. In my
view, we have *5* different language constructs: `foreign import',
`foreign import dynamic', `foreign export', `foreign export dynamic',
and `foreign label'. GC-/concurrency-related modifiers or calling
conventions on the other hand do not change the basic meaning of a
foreign declaration.
* Because of the reason stated above, I think static/dynamic *must*
come first after import/export, but the order of unsafe/safe,
callconv, and extent should not matter. The var (*not* varid, it was
a design flaw IMHO) must be the last thing before the colon,
otherwise it tends to drown in the syntax. Another possibility would
be a rather strict order on the syntactic entities, but that's not of
paramount importance.
* Will the calling convention have influence on the typing of a foreign
declaration? ccall vs. wincall obviously doesn't, but I'm not sure
about the other conventions. I haven't thought very deeply about this
yet, but this would be an unfortunate situation.
* Some care should be taken to be backwards compatible with the
existing FFI, e.g. a plain
foreign import sin :: Double -> Double
should still be valid, at least for a transition time, and should
mean the same thing as
foreign import ccall safe static "sin" sin :: Double -> Double
in Manuel's syntax, probably yielding a deprecation warning.
* IIRC we concluded some time ago that it's not feasible to mirror all
strange typing phenomena on the foreign side in the Haskell type,
e.g. const modifiers, arrays vs. pointers to elements, etc. But I
can't find anything in this proposal to specify these things, e.g. in
the extent or something else.
* What about automatic prototype generation for ccall/wincall
functions? Even if don't require such a thing, this problems related
to this topic should be mentioned somewhere.
* I don't understand the last part of section 3.2.1, mentioning the
loading of dynamically loaded libs. Is something like dlopen() meant
here or linking against a libfoo.so? And the details of how/when this
linking should be done are completely obscure to me.
* How will we differentiate between virtual vs. non-virtual methods in
the cplusplus calling convention? What about class methods vs.
instance methods? Will these distinctions have influence on the
typing rules? If yes, coding this into the extent would be wrong.
* The JVM has *4* different instructions for method invocation
(invokeinterface, invokespecial, invokestatic, and invokevirtual), so
our static/dynamic distinction seems a bit inflexible here. And the
introduction of the "new" prefix looks like a hack, which doesn't
even handle all situations.
* The JVM instructions mentioned above can be categorized into two
kinds: The first kind expects an object reference in addition to the
actual arguments (invokeinterface, invokespecial, invokevirtual), the
second kind doesn't (invokestatic). When we export a Haskell function
to the JVM, how do we specify this distinction? static vs. dynamic?
This means something slightly different in the case of
ccall/wincall. What about typing?
* How are C++/JVM exceptions handled? I fear that almost no real
C++/Java code will be useable from the Haskell side if there is no
way to catch these beasts or throw them.
I hope I didn't sound too negative, that's not what was intended. It's
only a mirror of the fact that there are a lot of loose ends in the spec
and a multi-language FFI in a strongly type language is a rather
ambitious (but very cool :-) project. Thanks to Manuel for his effort!
Cheers,
Sven
More information about the FFI
mailing list