mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 11:40:18 +02:00
initial VM support for delimited continuations and dynamic-wind
* libguile/vm-i-system.c (prompt, wind, throw, unwind): New instructions, for implementing dynamic-wind and delimited continuations. * libguile/vm.c: Add some stub support for the new instructions. * libguile/vm-engine.c: Some new error conditions.
This commit is contained in:
parent
17d819d4c4
commit
4f66bcdeff
3 changed files with 108 additions and 0 deletions
|
@ -214,6 +214,12 @@ VM_NAME (SCM vm, SCM program, SCM *argv, int nargs)
|
|||
/* shouldn't get here */
|
||||
goto vm_error;
|
||||
|
||||
vm_error_not_a_thunk:
|
||||
SYNC_ALL ();
|
||||
scm_wrong_type_arg_msg (FUNC_NAME, 1, finish_args, "thunk");
|
||||
/* shouldn't get here */
|
||||
goto vm_error;
|
||||
|
||||
vm_error_no_values:
|
||||
err_msg = scm_from_locale_string ("Zero values returned to single-valued continuation");
|
||||
finish_args = SCM_EOL;
|
||||
|
|
|
@ -1433,6 +1433,87 @@ VM_DEFINE_INSTRUCTION (82, make_symbol, "make-symbol", 0, 1, 1)
|
|||
NEXT;
|
||||
}
|
||||
|
||||
VM_DEFINE_INSTRUCTION (83, prompt, "prompt", 5, 3, 0)
|
||||
{
|
||||
scm_t_int32 offset;
|
||||
scm_t_uint8 inline_handler_p, escape_only_p;
|
||||
SCM k, handler, pre_unwind, jmpbuf;
|
||||
|
||||
inline_handler_p = FETCH ();
|
||||
escape_only_p = FETCH ();
|
||||
FETCH_OFFSET (offset);
|
||||
POP (pre_unwind);
|
||||
POP (handler);
|
||||
POP (k);
|
||||
|
||||
SYNC_REGISTER ();
|
||||
/* Push the prompt onto the dynamic stack. The setjmp itself has to be local
|
||||
to this procedure. */
|
||||
jmpbuf = vm_prepare_prompt_jmpbuf (vm, k, handler, pre_unwind,
|
||||
inline_handler_p, escape_only_p);
|
||||
if (VM_SETJMP (jmpbuf))
|
||||
{
|
||||
/* The prompt exited nonlocally. Cache the regs back from the vp, and go
|
||||
to the handler or post-handler label. (The meaning of the label differs
|
||||
depending on whether the prompt's handler is rendered inline or not.)
|
||||
*/
|
||||
CACHE_REGISTER (); /* Really we only need SP. FP and IP should be
|
||||
unmodified. */
|
||||
ip += offset;
|
||||
NEXT;
|
||||
}
|
||||
|
||||
/* Otherwise setjmp returned for the first time, so we go to execute the
|
||||
prompt's body. */
|
||||
NEXT;
|
||||
}
|
||||
|
||||
VM_DEFINE_INSTRUCTION (85, wind, "wind", 0, 2, 0)
|
||||
{
|
||||
SCM wind, unwind;
|
||||
POP (unwind);
|
||||
POP (wind);
|
||||
SYNC_REGISTER ();
|
||||
/* Push wind and unwind procedures onto the dynamic stack. Note that neither
|
||||
are actually called; the compiler should emit calls to wind and unwind for
|
||||
the normal dynamic-wind control flow. */
|
||||
if (SCM_UNLIKELY (scm_is_false (scm_thunk_p (wind))))
|
||||
{
|
||||
finish_args = wind;
|
||||
goto vm_error_not_a_thunk;
|
||||
}
|
||||
if (SCM_UNLIKELY (scm_is_false (scm_thunk_p (unwind))))
|
||||
{
|
||||
finish_args = unwind;
|
||||
goto vm_error_not_a_thunk;
|
||||
}
|
||||
scm_i_set_dynwinds (scm_cons (scm_cons (wind, unwind), scm_i_dynwinds ()));
|
||||
NEXT;
|
||||
}
|
||||
|
||||
VM_DEFINE_INSTRUCTION (86, throw, "throw", 1, -1, -1)
|
||||
{
|
||||
unsigned n = FETCH ();
|
||||
SCM k;
|
||||
SCM args;
|
||||
POP_LIST (n);
|
||||
POP (args);
|
||||
POP (k);
|
||||
SYNC_REGISTER ();
|
||||
vm_throw (vm, k, args);
|
||||
/* vm_throw should not return */
|
||||
abort ();
|
||||
}
|
||||
|
||||
VM_DEFINE_INSTRUCTION (87, unwind, "unwind", 0, 0, 0)
|
||||
{
|
||||
/* A normal exit from the dynamic extent of an expression. Pop the top entry
|
||||
off of the dynamic stack. */
|
||||
scm_i_set_dynwinds (scm_cdr (scm_i_dynwinds ()));
|
||||
NEXT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
(defun renumber-ops ()
|
||||
|
|
|
@ -169,6 +169,27 @@ vm_dispatch_hook (SCM vm, int hook_num)
|
|||
vp->trace_level++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The dynamic stack
|
||||
*/
|
||||
static SCM
|
||||
vm_prepare_prompt_jmpbuf (SCM vm, SCM k, SCM handler, SCM pre_unwind,
|
||||
scm_t_uint8 inline_p, scm_t_uint8 escape_only_p)
|
||||
{
|
||||
abort ();
|
||||
return SCM_BOOL_F;
|
||||
}
|
||||
|
||||
#define VM_SETJMP(jmpbuf) 0
|
||||
|
||||
static void vm_throw (SCM vm, SCM k, SCM args) SCM_NORETURN;
|
||||
static void
|
||||
vm_throw (SCM vm, SCM k, SCM args)
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* VM Internal functions
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue