Next: , Previous: Accessing Scheme data from C, Up: C interface


7.6 Calling Scheme procedures from C

— C function: s48_value s48_call_scheme (s48_value proc, long nargs, ...)

Calls the Scheme procedure proc on nargs arguments, which are passed as additional arguments to s48_call_scheme. There may be at most twelve arguments. The value returned by the Scheme procedure is returned to the C procedure. Calling any Scheme procedure may potentially cause a garbage collection.

There are some complications that arise when mixing calls from C to Scheme with continuations & threads. C supports only downward continuations (via longjmp()). Scheme continuations that capture a portion of the C stack have to follow the same restriction. For example, suppose Scheme procedure s0 captures continuation a and then calls C function c0, which in turn calls Scheme procedure s1. S1 can safely call the continuation a, because that is a downward use. When a is called, Scheme48 will remove the portion of the C stack used by the call to c0. On the other hand, if s1 captures a continuation, that continuation cannot be used from s0, because, by the time control returns to s0, the C stack used by s0 will no longer be valid. An attempt to invoke an upward continuation that is closed over a portion of the C stack will raise an exception.

In Scheme48, threads are implemented using continuations, so the downward restriction applies to them as well. An attempt to return from Scheme to C at a time when the appropriate C frame is not on the top of the C stack will cause the current thread to block until the frame is available. For example, suppose thread t0 calls a C function that calls back to Scheme, at which point control switches to thread t1, which also calls C & then back to Scheme. At this point, both t0 & t1 have active calls to C on the C stack, with t1's C frame above t0's. If t0 attempts to return from Scheme to C, it will block, because the frame is not yet accessible. Once t1 has returned to C and from there back to Scheme, t0 will be able to resume. The return to Scheme is required because context switches can occur only while Scheme code is running. T0 will also be able to resume if t1 uses a continuation to throw past its call out to C.