On 15-Apr-2004, Sven Panne <[EMAIL PROTECTED]> wrote: > Fergus Henderson wrote: > >I'd rather fix GHC so that interfacing with C macros works with ghc -fasm. > >The equivalent works fine with the Mercury implementation ("mmc --target > >asm" > >generates assembler for the Mercury code and C stubs for the FFI glue), > >so it's clearly possible. > > How does Mercury handle something like the "broken" macros we discussed > recently in its different back-ends?
The macros, of course, are not broken; it the handling of them by Hugs/GHC and/or the Haskell FFI that is broken :) In Mercury, it would look like this: :- module ffi_example. :- interface. :- import_module io. :- type window. :- pred wstandend(window::in, io::di, io::uo) is det. :- implementation. :- pragma foreign_decl("C", "#include <curses.h>"). :- pragma foreign_type("C", window, "WINDOW *"). :- pragma import(wstandend(in,di,uo), [will_not_call_mercury], "wstandend"). When using the "--target asm" option, which tells the Mercury compiler to compile directly to assembler, the Mercury compiler will generate some C glue code to handle the FFI interfacing pragmas. The glue code calls the wstandend() macro with a variable of type "WINDOW *" as its argument: #include "mercury.h" #include <curses.h> void ffi_example__wstandend_3_p_0(void *ffi_example__Arg1_1) { { WINDOW * Arg1; MR_MAYBE_UNBOX_FOREIGN_TYPE(WINDOW *, ffi_example__Arg1_1, Arg1); wstandend(Arg1); } The macro MR_MAYBE_UNBOX_FOREIGN_TYPE converts from "void *" to "WINDOW *". If sizeof(void *) == sizeof(WINDOW *), as is the case on most architectures, the macro will end up just doing an assignment; but if the C type is one that doesn't fit in a void *, it will get boxed when passed from C to Mercury and unboxed when passed from Mercury to C. This generated C glue code will be compiled with a C compiler. Then for any Mercury code which calls the "wstandend" Mercury procedure, we will generate assembler code which calls the C function in our generated glue code. For example, if you have :- pred foo(window::in, io::di, io::uo) is det. foo(W) --> wstandend(W). then the Mercury compiler will generate the following assembly code: .globl ffi_example__foo_3_p_0 .type ffi_example__foo_3_p_0,@function ffi_example__foo_3_p_0: jmp ffi_example__wstandend_3_p_0 .Lfe5: .size ffi_example__foo_3_p_0,.Lfe5-ffi_example__foo_3_p_0 -- Fergus J. Henderson | "I have always known that the pursuit Galois Connections, Inc. | of excellence is a lethal habit" Phone: +1 503 626 6616 | -- the last words of T. S. Garp. _______________________________________________ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi