[clean-list] calling heaven from hell

John van Groningen johnvg@cs.kun.nl
Fri, 12 Jan 2001 11:39:18 +0000


>calling hell from heaven, i.e. calling c from clean is possible with
>the H to Clean 1.0 package.
<
>Unfortunately the other way round, as I learn from the H to Clean 1.0
>documentation, is not possible: calling my nice Clean function
> f:: String -> String=20
>from C; or is there a some hidden way to do this?

It is not possible with H to Clean, but some support for calling Clean from
C is available in Clean 1.3.3 for windows and mac os (and probably for linux
as well). But it is not easy to use, still very limited and not documented.

The abc instruction 'centry' can be used to generate a conversion function
for a Clean function that can can be called from C. Currently only strict
integer parameters and results are supported (multiple integer results
are supported in the same way as in htoclean using tuples in Clean and
pointers in C).

The syntax of the centry abc instruction is:

  centry c_function_name clean_strict_entry_label_name parameter_string

where 'c_function_name' is the name of the function in C,
'clean_strict_entry_label_name' is the label of the strict entry of the
Clean function. If a Clean function (fun) is exported from a module (mod)
(and is not overloaded), this label will be e_mod_sfun.
The parameter string is a string with an I for each integer parameter,
followed by a ':', and an I for each integer result (just like for the
ccall instructions generated by htoclean).

=46or example to call a Clean function 'f' in module 'test' with type:

f :: !Int !Int -> Int

we generate the conversion function using the abc instruction:

  centry f e_test_sf "II:I"

Because the front end of the Clean compiler does not yet have any support
for this interface, we use the following trick to pass the centry abc
instruction to the code generator. We put this abc instruction in the code
block of a function that is not used. This function has to be exported (by=
 specifying the function type in the definition module), because otherwise=
 the compiler would not generate any code for this function.=20

=46or example in the .icl module we write:

f_c :: Int;
f_c =3D code {
        pushI 0
        .d 0 1 i
        rtn

        centry f e_test_sf "II:"
       =20
        pushI 0
      }

and in the .dcl module:

f_c :: Int;

You can put more centry instructions in the code block and the name of this
function ('f_c' in this case) does not matter.

The Clean function that will be called has to be exported as well, even if=
 it referenced, because otherwise the compiler will generated a different=
 label for the strict entry of the function.

A conversion function generated by centry uses some global variables that
contain information about the Clean runtime system (a stack pointer, end of
heap pointer, etc).
These global variables have to be initialised with the current values before=
 a conversion function can be used.
This has to be done when a Clean function calls a C function that might call
a Clean function. The ccall's that are generated by htoclean don't do this,
but can easily be changed by adding a G at the start of the parameter_string=
 of the ccall. For example change:
  ccall f "II:I"
into:
  ccall f "GII:I"

>Currently my clean program is started as an executable and communicates
>via files, which is not very nice...

In a future version of Clean it will be possible to generate a DLL instead
of an executable. Functions in the DLL can then be called using this C to=
 Clean interface. This has been partly implemented: the runtime system has=
 already been modified (by adding a DLL initialization function) and the=
 linker can generated DLL's (but the IDE does not yet support this).

Regards,
John van Groningen