Index: trunk/src/interpret.c
===================================================================
--- trunk/src/interpret.c	(Revision 2314)
+++ trunk/src/interpret.c	(Arbeitskopie)
@@ -269,6 +269,11 @@
     svalue_t             * save_sp;
       /* The saved global values
        */
+
+    svalue_t catch_value;
+      /* Holds the value throw()n from within a catch() while the throw
+       * is executed.
+       */
 };
 
 /* --- struct cache: one entry of the apply cache
@@ -569,12 +574,7 @@
    * is the real bottom of the stack.
    */
 
-svalue_t catch_value = { T_INVALID } ;
-  /* Holds the value throw()n from within a catch() while the throw
-   * is executed.
-   */
 
-
 #if MAX_USER_TRACE >= MAX_TRACE
 #error MAX_USER_TRACE value must be smaller than MAX_TRACE!
 #endif
@@ -6699,6 +6699,7 @@
     p->recovery_info.rt.last = rt_context;
     p->recovery_info.rt.type = ERROR_RECOVERY_CATCH;
     p->recovery_info.flags = catch_flags;
+    p->catch_value.type = T_INVALID;
     rt_context = (rt_context_t *)&p->recovery_info;
     return &p->recovery_info.con;
 } /* push_error_context() */
@@ -6733,7 +6734,7 @@
 
 /*-------------------------------------------------------------------------*/
 svalue_t *
-pull_error_context (svalue_t *sp)
+pull_error_context (svalue_t *sp, svalue_t *msg)
 
 /* Restore the context saved by a catch() after a throw() or runtime error
  * occured. <sp> is the current stackpointer and is used to pop the elements
@@ -6742,6 +6743,8 @@
  * The function pops the topmost recovery entry, which must be the catch
  * recovery entry, restores the important global variables and returns
  * the saved stack pointer.
+ *
+ * If <msg> is not NULL the caught error message is put there.
  */
 
 {
@@ -6780,6 +6783,12 @@
     csp = p->save_csp;
     pop_n_elems(sp - p->save_sp);
     command_giver = p->save_command_giver;
+    
+    /* Save the error message */
+    if (msg)
+        transfer_svalue_no_free(msg, &p->catch_value);
+    else
+        free_svalue(&p->catch_value);
 
     /* Remove the context from the context stack */
     rt_context = p->recovery_info.rt.last;
@@ -6790,6 +6799,19 @@
 
 /*-------------------------------------------------------------------------*/
 void
+transfer_error_message (svalue_t *v, rt_context_t *rt)
+ /* Saves the message <v> in the error context <rt> assuming that
+  * it's a catch recovery context. <v> is freed afterwards.
+  */
+{
+    struct catch_context *p;
+
+    p = (struct catch_context *)rt;
+    transfer_svalue_no_free(&p->catch_value, v);
+}
+
+/*-------------------------------------------------------------------------*/
+void
 push_control_stack ( svalue_t   *sp
                    , bytecode_p  pc
                    , svalue_t   *fp
@@ -15955,10 +15977,9 @@
          */
 
         assign_eval_cost();
-        transfer_svalue_no_free(&catch_value, sp--);
-        inter_sp = sp;
+        inter_sp = --sp;
         inter_pc = pc;
-        throw_error(); /* do the longjump, with extra checks... */
+        throw_error(sp+1); /* do the longjump, with extra checks... */
         break;
 
     /* --- Efuns: Strings --- */
Index: trunk/src/interpret.h
===================================================================
--- trunk/src/interpret.h	(Revision 2314)
+++ trunk/src/interpret.h	(Arbeitskopie)
@@ -108,7 +108,6 @@
 extern int32  eval_cost;
 extern int32  assigned_eval_cost;
 extern svalue_t apply_return_value;
-extern svalue_t catch_value;
 extern svalue_t last_indexing_protector;
 
 #ifdef APPLY_CACHE_STAT
@@ -138,7 +137,8 @@
 extern void pop_control_stack(void);
 extern struct longjump_s *push_error_context(svalue_t *sp, int catch_flags);
 extern void pop_error_context (void);
-extern svalue_t *pull_error_context (svalue_t *sp);
+extern svalue_t *pull_error_context (svalue_t *sp, svalue_t *msg);
+extern void transfer_error_message (svalue_t *v, rt_context_t *rt);
 extern Bool destructed_object_ref (svalue_t *svp);
 extern void free_object_svalue(svalue_t *v);
 extern void zero_object_svalue(svalue_t *v);
Index: trunk/src/simulate.c
===================================================================
--- trunk/src/simulate.c	(Revision 2314)
+++ trunk/src/simulate.c	(Arbeitskopie)
@@ -392,9 +392,10 @@
          * the global <catch_value>.
          */
         svalue_t *sp;
+        svalue_t catch_value;
 
         /* Remove the catch context and get the old stackpointer setting */
-        sp = pull_error_context(INTER_SP);
+        sp = pull_error_context(INTER_SP, &catch_value);
 
         /* beware of errors after set_this_object() */
         current_object = csp->ob;
@@ -407,7 +408,6 @@
 
         /* Push the catch return value */
         *(++sp) = catch_value;
-        catch_value.type = T_INVALID;
 
         *i_sp = (volatile svalue_t *)sp;
 
@@ -801,7 +801,12 @@
             string_t * str = new_mstring(emsg_buf);
 
             if (NULL != str)
-                put_string(&catch_value, str);
+            {
+                svalue_t stmp;
+
+                put_string(&stmp, str);
+                transfer_error_message(&stmp, rt);
+            }
             else
             {
                 error_caught = MY_FALSE;
@@ -1325,21 +1330,21 @@
 
 /*-------------------------------------------------------------------------*/
 void
-throw_error()
+throw_error (svalue_t *v)
 
-/* The second part of the efun throw(): the caller stored the message
- * into catch_value, now our job is to do the proper longjmp.
+/* The efun throw(). We have to save the message <v> in the
+ * error context and then do the proper longjmp. <v> is freed.
  */
 
 {
     unroll_context_stack();
     if (rt_context->type >= ERROR_RECOVERY_CATCH)
     {
+        transfer_error_message(v, rt_context);
         longjmp(((struct error_recovery_info *)rt_context)->con.text, 1);
         fatal("Throw_error failed!");
     }
-    free_svalue(&catch_value);
-    catch_value.type = T_INVALID;
+    free_svalue(v);
     errorf("Throw with no catch.\n");
 } /* throw_error() */
 
Index: trunk/src/simulate.h
===================================================================
--- trunk/src/simulate.h	(Revision 2314)
+++ trunk/src/simulate.h	(Arbeitskopie)
@@ -278,7 +278,7 @@
 extern void warnf VARPROT((char *, ...), printf, 1, 2);
 extern void errorf VARPROT((const char *, ...), printf, 1, 2) NORETURN;
 extern void fatal VARPROT((const char *, ...), printf, 1, 2) NORETURN;
-extern void throw_error(void);
+extern void throw_error(svalue_t *v);
 extern char *limit_error_format(char *fixed_fmt, size_t fixed_fmt_len, const char *fmt);
 extern Bool legal_path(const char *path);
 extern Bool check_no_parentdirs(const char *path);
