Scheme 48 Manual | Contents | In Chapter: Mixing Scheme 48 and C
Previous: Accessing Scheme data from C | Next: Interacting with the Scheme heap

Calling Scheme functions from C

External code that has been called from Scheme can call back to Scheme procedures using the following function.

This calls the Scheme procedure p 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 by the C procedure. Invoking any Scheme procedure may potentially cause a garbage collection.

There are some complications that occur when mixing calls from C to Scheme with continuations and threads. C only supports 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 procedure c0, which in turn calls Scheme procedure s1. Procedure s1 can safely call the continuation a, because that is a downward use. When a is called Scheme 48 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 c0 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 Scheme 48 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 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 procedure which calls back to Scheme, at which point control switches to thread t1, which also calls C and then back to Scheme. At this point both t0 and t1 have active calls to C on the C stack, with t1's C frame above t0's. If thread t0 attempts to return from Scheme to C it will block, as its frame is not accessible. Once t1 has returned to C and from there to Scheme, t0 will be able to resume. The return to Scheme is required because context switches can only occur while Scheme code is running. T0 will also be able to resume if t1 uses a continuation to throw past its call to C.

Previous: Accessing Scheme data from C | Next: Interacting with the Scheme heap