caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Q: How to call a CSL function from C
@ 1995-12-15 12:40 Leszek.Holenderski
  1995-12-15 16:33 ` Xavier Leroy
  0 siblings, 1 reply; 2+ messages in thread
From: Leszek.Holenderski @ 1995-12-15 12:40 UTC (permalink / raw)
  To: caml-list


Hi Camlers,

Is there any official way to call a CSL function from C? CSL 1.12 manual
doesn't seem to mention anything about the subject.

I need to call some f: 'a -> 'b (in fact, 'a and 'b are some concrete
types, but it doesn't matter here) from my C code linked with CSL 1.12. In
my Caml code, I'll have the function

  external register_callback: ('a -> 'b) -> unit = "register_callback"

such that 'register_callback f' will store, in my C code, enough
information to call f later from the C code.

I suppose the C function for calling f should have the following pattern:

  value invoke_callback (f_info, arg);
    ... f_info;
    value arg;
  {
    value closure;
    closure = ... extract/build f's closure from f_info ...;
    return callback(closure, arg);  /* 'callback' is from interp.h */
  }

A simple solution would be to keep f's closure as f_info:

  static value f_closure = NULL;

  value register_callback (f);
    value f;
  {f_closure = f; return Val_unit;}

  value invoke_callback (f, arg);
    value f, arg;
  {return callback(f, arg);}

  ... invoke_callback(f_closure, something); ...

but I suspect it's too naive, since f's closure could be reallocated by GC,
between register_callback and invoke_callback.

The following code, borrowed from CamlTk for CL 0.7 (thus, from Francois
Rouaix), seems to avoid the problem:

  static code_t f_code = NULL;

  value register_callback (f);
    value f;
  {f_code = Code_val(f); return Val_unit;}

  value invoke_callback (f, arg);
    code_t f;
    value arg;
  {
    value closure;
    closure = alloc(2, Closure_tag);
    Code_val(closure) = f;
    Env_val(closure) = Atom(0);
    return callback(closure, arg);
  }

  ... invoke_callback(f_code, something); ...

When trying to port the code from CL 0.7 to CSL 1.12, I encountered the
following problems:

1. How to port the innocently looking 'Env_val(closure) = Atom(0)' if
Env_val seems to disappear in CSL 1.12.

2. Does Atom(0) still represent the empty environment? Or maybe Val_int(0)
is used for the purpose? (The later possibility came to my mind since
Val_unit used to be Atom(0), in CL, but it is  Val_int(0), in CSL.)

3. What are atoms used for in CSL 1.12, anyway? (In CL 0.7, they were used
for representing constant constructors. In CSl 1.12, constant constructors
are represented by integers.)

4. What functions survive GC? More precisely, for what f, Code_val(f) is
not changed by GC? Only for those which are declared on the top level?

Any help will be appreciated.

Cheers,
Leszek







+---------------------------------+-------------------------+
| Leszek Holenderski              | room  C2-222            |
| GMD-I5.SKS                      | phone ++ 02241 142412   |
| Schloss Birlinghoven            | fax   ++ 02241 142035   |
| Postfach 1316                   | email lhol@gmdzi.gmd.de |
| 53757 Sankt Augustin 1, Germany |                         |
+---------------------------------+-------------------------+

GMD = Gesellschaft fuer Mathematik und Datenverarbeitung, i.e.
      National Research Centre for Comp. Sci.






^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Q: How to call a CSL function from C
  1995-12-15 12:40 Q: How to call a CSL function from C Leszek.Holenderski
@ 1995-12-15 16:33 ` Xavier Leroy
  0 siblings, 0 replies; 2+ messages in thread
From: Xavier Leroy @ 1995-12-15 16:33 UTC (permalink / raw)
  To: Leszek.Holenderski; +Cc: caml-list


> I need to call some f: 'a -> 'b (in fact, 'a and 'b are some concrete
> types, but it doesn't matter here) from my C code linked with CSL 1.12. In
> my Caml code, I'll have the function
> 
>   external register_callback: ('a -> 'b) -> unit = "register_callback"
> 
> such that 'register_callback f' will store, in my C code, enough
> information to call f later from the C code.

The correct way to do this is as follows (modified from your pseudocode):

    static value f_closure = Val_int(0)
 
    value register_callback (f);
      value f;
    {
      register_global_root(&f_closure);
      f_closure = f;
      return Val_unit;
    }
 
    value invoke_f (arg)
      value arg;
    {
      return callback(f_closure, arg);
    }

The call to "register_global_root" ensures that the GC will not
deallocate the closure and will update the variable f_closure if the
closure gets moved. (This is documented in the user's manual.)

> The following code, borrowed from CamlTk for CL 0.7 (thus, from Francois
> Rouaix), seems to avoid the problem:

That was a terrible hack to work around the lack of a
"register_global_root" function in Caml Light 0.7. Forget about it.

- Xavier Leroy




^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~1995-12-15 17:52 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1995-12-15 12:40 Q: How to call a CSL function from C Leszek.Holenderski
1995-12-15 16:33 ` Xavier Leroy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).