mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-16 16:50:21 +02:00
Continuations are RTL stubs
* libguile/continuations.h: * libguile/continuations.c: Reimplement continuations and the call_cc stub as RTL programs. * libguile/programs.c (scm_i_rtl_program_minimum_arity): Add a case for continuations. * libguile/vm-engine.c (rtl_vm_debug_engine): Always call the abort continuation hook with the number of non-procedure locals. Fix compose-continuation argument count. Enable call/cc.
This commit is contained in:
parent
8bd261baaa
commit
d691ac2069
4 changed files with 61 additions and 115 deletions
|
@ -849,7 +849,7 @@ RTL_VM_NAME (SCM vm, SCM program, SCM *argv, size_t nargs_)
|
|||
to pull all our state back from the ip/fp/sp.
|
||||
*/
|
||||
CACHE_REGISTER ();
|
||||
ABORT_CONTINUATION_HOOK (fp, FRAME_LOCALS_COUNT());
|
||||
ABORT_CONTINUATION_HOOK (fp, FRAME_LOCALS_COUNT () - 1);
|
||||
NEXT (0);
|
||||
}
|
||||
|
||||
|
@ -1252,7 +1252,7 @@ RTL_VM_NAME (SCM vm, SCM program, SCM *argv, size_t nargs_)
|
|||
scm_i_check_continuation (contregs);
|
||||
vm_return_to_continuation (scm_i_contregs_vm (contregs),
|
||||
scm_i_contregs_vm_cont (contregs),
|
||||
FRAME_LOCALS_COUNT (), fp);
|
||||
FRAME_LOCALS_COUNT () - 1, fp);
|
||||
scm_i_reinstate_continuation (contregs);
|
||||
|
||||
/* no NEXT */
|
||||
|
@ -1278,7 +1278,7 @@ RTL_VM_NAME (SCM vm, SCM program, SCM *argv, size_t nargs_)
|
|||
SYNC_IP ();
|
||||
VM_ASSERT (SCM_VM_CONT_REWINDABLE_P (vmcont),
|
||||
vm_error_continuation_not_rewindable (vmcont));
|
||||
vm_reinstate_partial_continuation (vm, vmcont, FRAME_LOCALS_COUNT (), fp,
|
||||
vm_reinstate_partial_continuation (vm, vmcont, FRAME_LOCALS_COUNT () - 1, fp,
|
||||
¤t_thread->dynstack,
|
||||
®isters);
|
||||
CACHE_REGISTER ();
|
||||
|
@ -1333,14 +1333,14 @@ RTL_VM_NAME (SCM vm, SCM program, SCM *argv, size_t nargs_)
|
|||
/* call/cc _:24
|
||||
*
|
||||
* Capture the current continuation, and tail-apply the procedure in
|
||||
* local slot 0 to it. This instruction is part of the implementation
|
||||
* local slot 1 to it. This instruction is part of the implementation
|
||||
* of `call/cc', and is not generated by the compiler.
|
||||
*/
|
||||
VM_DEFINE_OP (12, call_cc, "call/cc", OP1 (U8_X24))
|
||||
#if 0
|
||||
{
|
||||
SCM vm_cont, cont;
|
||||
scm_t_dynstack *dynstack;
|
||||
int first;
|
||||
|
||||
VM_HANDLE_INTERRUPTS;
|
||||
|
||||
|
@ -1353,23 +1353,34 @@ RTL_VM_NAME (SCM vm, SCM program, SCM *argv, size_t nargs_)
|
|||
SCM_FRAME_MV_RETURN_ADDRESS (fp),
|
||||
dynstack,
|
||||
0);
|
||||
cont = scm_i_make_continuation (®isters, vm, vm_cont);
|
||||
/* FIXME: Seems silly to capture the registers here, when they are
|
||||
already captured in the registers local, which here we are
|
||||
copying out to the heap; and likewise, the setjmp(®isters)
|
||||
code already has the non-local return handler. But oh
|
||||
well! */
|
||||
cont = scm_i_make_continuation (&first, vm, vm_cont);
|
||||
|
||||
fp[-1] = fp[0];
|
||||
fp[0] = cont;
|
||||
RESET_FRAME (2);
|
||||
if (first)
|
||||
{
|
||||
LOCAL_SET (0, LOCAL_REF (1));
|
||||
LOCAL_SET (1, cont);
|
||||
RESET_FRAME (2);
|
||||
|
||||
APPLY_HOOK ();
|
||||
APPLY_HOOK ();
|
||||
|
||||
if (SCM_UNLIKELY (!SCM_RTL_PROGRAM_P (SCM_FRAME_PROGRAM (fp))))
|
||||
goto apply;
|
||||
if (SCM_UNLIKELY (!SCM_RTL_PROGRAM_P (SCM_FRAME_PROGRAM (fp))))
|
||||
goto apply;
|
||||
|
||||
ip = SCM_RTL_PROGRAM_CODE (SCM_FRAME_PROGRAM (fp));
|
||||
NEXT (0);
|
||||
ip = SCM_RTL_PROGRAM_CODE (SCM_FRAME_PROGRAM (fp));
|
||||
NEXT (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
CACHE_REGISTER ();
|
||||
ABORT_CONTINUATION_HOOK (fp, FRAME_LOCALS_COUNT () - 1);
|
||||
NEXT (0);
|
||||
}
|
||||
}
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue