summaryrefslogtreecommitdiff
path: root/libguile/continuations.c
diff options
context:
space:
mode:
Diffstat (limited to 'libguile/continuations.c')
-rw-r--r--libguile/continuations.c66
1 files changed, 34 insertions, 32 deletions
diff --git a/libguile/continuations.c b/libguile/continuations.c
index d9912783d..fe7618f5e 100644
--- a/libguile/continuations.c
+++ b/libguile/continuations.c
@@ -24,6 +24,7 @@
#include "libguile/_scm.h"
+#include <assert.h>
#include <string.h>
#include <stdio.h>
@@ -33,7 +34,7 @@
#include "libguile/stackchk.h"
#include "libguile/smob.h"
#include "libguile/ports.h"
-#include "libguile/dynwind.h"
+#include "libguile/dynstack.h"
#include "libguile/eval.h"
#include "libguile/vm.h"
#include "libguile/instructions.h"
@@ -52,7 +53,6 @@ static scm_t_bits tc16_continuation;
#define SCM_SET_CONTINUATION_LENGTH(x, n)\
(SCM_CONTREGS (x)->num_stack_items = (n))
#define SCM_JMPBUF(x) ((SCM_CONTREGS (x))->jmpbuf)
-#define SCM_DYNENV(x) ((SCM_CONTREGS (x))->dynenv)
#define SCM_CONTINUATION_ROOT(x) ((SCM_CONTREGS (x))->root)
#define SCM_DFRAME(x) ((SCM_CONTREGS (x))->dframe)
@@ -173,14 +173,25 @@ continuation_print (SCM obj, SCM port, scm_print_state *state SCM_UNUSED)
{
scm_t_contregs *continuation = SCM_CONTREGS (obj);
- scm_puts ("#<continuation ", port);
+ scm_puts_unlocked ("#<continuation ", port);
scm_intprint (continuation->num_stack_items, 10, port);
- scm_puts (" @ ", port);
+ scm_puts_unlocked (" @ ", port);
scm_uintprint (SCM_SMOB_DATA_1 (obj), 16, port);
- scm_putc ('>', port);
+ scm_putc_unlocked ('>', port);
return 1;
}
+/* James Clark came up with this neat one instruction fix for
+ * continuations on the SPARC. It flushes the register windows so
+ * that all the state of the process is contained in the stack.
+ */
+
+#if defined (sparc) || defined (__sparc__) || defined (__sparc)
+# define SCM_FLUSH_REGISTER_WINDOWS asm("ta 3")
+#else
+# define SCM_FLUSH_REGISTER_WINDOWS /* empty */
+#endif
+
/* this may return more than once: the first time with the escape
procedure, then subsequently with SCM_UNDEFINED (the vals already having been
placed on the VM stack). */
@@ -200,7 +211,6 @@ scm_i_make_continuation (int *first, SCM vm, SCM vm_cont)
+ (stack_size - 1) * sizeof (SCM_STACKITEM),
"continuation");
continuation->num_stack_items = stack_size;
- continuation->dynenv = scm_i_dynwinds ();
continuation->root = thread->continuation_root;
src = thread->continuation_base;
#if ! SCM_STACK_GROWS_UP
@@ -323,33 +333,25 @@ grow_stack (SCM cont)
* own frame are overwritten. Thus, memcpy can be used for best performance.
*/
-typedef struct {
- scm_t_contregs *continuation;
- SCM_STACKITEM *dst;
-} copy_stack_data;
-
-static void
-copy_stack (void *data)
-{
- copy_stack_data *d = (copy_stack_data *)data;
- memcpy (d->dst, d->continuation->stack,
- sizeof (SCM_STACKITEM) * d->continuation->num_stack_items);
-#ifdef __ia64__
- SCM_I_CURRENT_THREAD->pending_rbs_continuation = d->continuation;
-#endif
-}
-
static void
copy_stack_and_call (scm_t_contregs *continuation,
SCM_STACKITEM * dst)
{
- long delta;
- copy_stack_data data;
+ scm_t_dynstack *dynstack;
+ scm_t_bits *joint;
+ scm_i_thread *thread = SCM_I_CURRENT_THREAD;
+
+ dynstack = SCM_VM_CONT_DATA (continuation->vm_cont)->dynstack;
+
+ joint = scm_dynstack_unwind_fork (&thread->dynstack, dynstack);
+
+ memcpy (dst, continuation->stack,
+ sizeof (SCM_STACKITEM) * continuation->num_stack_items);
+#ifdef __ia64__
+ thread->pending_rbs_continuation = continuation;
+#endif
- delta = scm_ilength (scm_i_dynwinds ()) - scm_ilength (continuation->dynenv);
- data.continuation = continuation;
- data.dst = dst;
- scm_i_dowinds (continuation->dynenv, delta, copy_stack, &data);
+ scm_dynstack_wind (&thread->dynstack, joint);
SCM_I_LONGJMP (continuation->jmpbuf, 1);
}
@@ -486,7 +488,7 @@ print_exception_and_backtrace (SCM port, SCM tag, SCM args)
if (should_print_backtrace (tag, stack))
{
- scm_puts ("Backtrace:\n", port);
+ scm_puts_unlocked ("Backtrace:\n", port);
scm_display_backtrace_with_highlights (stack, port,
SCM_BOOL_F, SCM_BOOL_F,
SCM_EOL);
@@ -531,7 +533,7 @@ pre_unwind_handler (void *error_port, SCM tag, SCM args)
{
/* Print the exception unless TAG is `quit'. */
if (!scm_is_eq (tag, scm_from_latin1_symbol ("quit")))
- print_exception_and_backtrace (PTR2SCM (error_port), tag, args);
+ print_exception_and_backtrace (SCM_PACK_POINTER (error_port), tag, args);
return SCM_UNSPECIFIED;
}
@@ -545,7 +547,7 @@ scm_c_with_continuation_barrier (void *(*func) (void *), void *data)
scm_i_with_continuation_barrier (c_body, &c_data,
c_handler, &c_data,
pre_unwind_handler,
- SCM2PTR (scm_current_error_port ()));
+ SCM_UNPACK_POINTER (scm_current_error_port ()));
return c_data.result;
}
@@ -589,7 +591,7 @@ SCM_DEFINE (scm_with_continuation_barrier, "with-continuation-barrier", 1,0,0,
return scm_i_with_continuation_barrier (scm_body, &scm_data,
scm_handler, &scm_data,
pre_unwind_handler,
- SCM2PTR (scm_current_error_port ()));
+ SCM_UNPACK_POINTER (scm_current_error_port ()));
}
#undef FUNC_NAME