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, ...)
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