* configure.in: New check for uca lib (needed for IA64 on HP-UX).
[bpt/guile.git] / libguile / continuations.c
index 50c460d..39785a5 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995,1996,1998,2000,2001,2004 Free Software Foundation, Inc.
+/* Copyright (C) 1995,1996,1998,2000,2001,2004, 2006 Free Software Foundation, Inc.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -12,7 +12,7 @@
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 
@@ -21,7 +21,9 @@
 #include "libguile/_scm.h"
 
 #include <string.h>
+#include <stdio.h>
 
+#include "libguile/async.h"
 #include "libguile/debug.h"
 #include "libguile/root.h"
 #include "libguile/stackchk.h"
@@ -90,18 +92,6 @@ continuation_print (SCM obj, SCM port, scm_print_state *state SCM_UNUSED)
   return 1;
 }
 
-#ifdef __ia64__
-/* Extern declaration of getcontext()/setcontext() in order to redefine
-   getcontext() since on ia64-linux the second return value indicates whether
-   it returned from getcontext() itself or by running setcontext(). */
-struct rv
-{
-  long retval;
-  long first_return;
-};
-extern struct rv ia64_getcontext (ucontext_t *) __asm__ ("getcontext");
-#endif /* __ia64__ */
-
 /* this may return more than once: the first time with the escape
    procedure, then subsequently with the value to be passed to the
    continuation.  */
@@ -114,9 +104,6 @@ scm_make_continuation (int *first)
   scm_t_contregs *continuation;
   long stack_size;
   SCM_STACKITEM * src;
-#ifdef __ia64__
-  struct rv rv;
-#endif /* __ia64__ */
 
   SCM_FLUSH_REGISTER_WINDOWS;
   stack_size = scm_stack_size (thread->continuation_base);
@@ -138,20 +125,23 @@ scm_make_continuation (int *first)
   memcpy (continuation->stack, src, sizeof (SCM_STACKITEM) * stack_size);
 
 #ifdef __ia64__
-  rv = ia64_getcontext (&continuation->ctx);
-  if (rv.first_return)
+  continuation->fresh = 1;
+  getcontext (&continuation->ctx);
+  if (continuation->fresh)
     {
-      continuation->backing_store_size = 
-        continuation->ctx.uc_mcontext.sc_ar_bsp - 
-        (unsigned long) __libc_ia64_register_backing_store_base;
+      continuation->backing_store_size =
+       (char *) scm_ia64_ar_bsp(&continuation->ctx)
+       -
+       (char *) scm_ia64_register_backing_store_base ();
       continuation->backing_store = NULL;
       continuation->backing_store = 
         scm_gc_malloc (continuation->backing_store_size,
                       "continuation backing store");
       memcpy (continuation->backing_store, 
-              (void *) __libc_ia64_register_backing_store_base
+              (void *) scm_ia64_register_backing_store_base ()
               continuation->backing_store_size);
       *first = 1;
+      continuation->fresh = 0;
       return cont;
     }
   else
@@ -246,7 +236,7 @@ copy_stack_and_call (scm_t_contregs *continuation, SCM val,
 
   continuation->throw_value = val;
 #ifdef __ia64__
-  memcpy ((void *) __libc_ia64_register_backing_store_base,
+  memcpy (scm_ia64_register_backing_store_base (),
           continuation->backing_store,
           continuation->backing_store_size);
   setcontext (&continuation->ctx);
@@ -267,6 +257,12 @@ scm_dynthrow (SCM cont, SCM val)
   SCM_STACKITEM *dst = thread->continuation_base;
   SCM_STACKITEM stack_top_element;
 
+  if (scm_i_critical_section_level)
+    {
+      fprintf (stderr, "continuation invoked from within critical section.\n");
+      abort ();
+    }
+
 #if SCM_STACK_GROWS_UP
   if (dst + continuation->num_stack_items >= &stack_top_element)
     grow_stack (cont, val);
@@ -304,7 +300,9 @@ SCM
 scm_i_with_continuation_barrier (scm_t_catch_body body,
                                 void *body_data,
                                 scm_t_catch_handler handler,
-                                void *handler_data)
+                                void *handler_data,
+                                scm_t_catch_handler pre_unwind_handler,
+                                void *pre_unwind_handler_data)
 {
   SCM_STACKITEM stack_item;
   scm_i_thread *thread = SCM_I_CURRENT_THREAD;
@@ -325,9 +323,10 @@ scm_i_with_continuation_barrier (scm_t_catch_body body,
   /* Call FUNC inside a catch all.  This is now guaranteed to return
      directly and exactly once.
   */
-  result = scm_internal_catch (SCM_BOOL_T,
-                              body, body_data,
-                              handler, handler_data);
+  result = scm_c_catch (SCM_BOOL_T,
+                       body, body_data,
+                       handler, handler_data,
+                       pre_unwind_handler, pre_unwind_handler_data);
 
   /* Return to old continuation root.
    */
@@ -356,7 +355,6 @@ static SCM
 c_handler (void *d, SCM tag, SCM args)
 {
   struct c_data *data = (struct c_data *)d;
-  scm_handle_by_message_noexit (NULL, tag, args);
   data->result = NULL;
   return SCM_UNSPECIFIED;
 }
@@ -368,7 +366,8 @@ scm_c_with_continuation_barrier (void *(*func) (void *), void *data)
   c_data.func = func;
   c_data.data = data;
   scm_i_with_continuation_barrier (c_body, &c_data,
-                                  c_handler, &c_data);
+                                  c_handler, &c_data,
+                                  scm_handle_by_message_noexit, NULL);
   return c_data.result;
 }
 
@@ -386,7 +385,6 @@ scm_body (void *d)
 static SCM
 scm_handler (void *d, SCM tag, SCM args)
 {
-  scm_handle_by_message_noexit (NULL, tag, args);
   return SCM_BOOL_F;
 }
 
@@ -407,7 +405,8 @@ SCM_DEFINE (scm_with_continuation_barrier, "with-continuation-barrier", 1,0,0,
   struct scm_data scm_data;
   scm_data.proc = proc;
   return scm_i_with_continuation_barrier (scm_body, &scm_data,
-                                         scm_handler, &scm_data);
+                                         scm_handler, &scm_data,
+                                         scm_handle_by_message_noexit, NULL);
 }
 #undef FUNC_NAME