External code that has been called from Scheme can call back to Scheme procedures using the following function.
scheme_value s48_call_scheme(s48_value p, long nargs, ...)
nargsarguments, 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
Scheme continuations that capture a portion of the C stack have to follow the
For example, suppose Scheme procedure
s0 captures continuation
and then calls C procedure
c0, which in turn calls Scheme procedure
s1 can safely call the continuation
a, because that
is a downward use.
a is called Scheme 48 will remove the portion of the C stack used
by the call to
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
t1 have active calls to C on the
C stack, with
t1's C frame above
t0 attempts to return from Scheme to C it will block,
as its frame is not accessible.
t1 has returned to C and from there to Scheme,
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