remerge of msvc re-raise exception patch from Alberto

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Another unmerged patch I'd like to see go in.  cppexcept.c has changed a 
bit since this was submitted so I've tried to merge in the changes (at 
a glance, this seems to have worked).  Let me know if there's anything 
that needs fixing before it can go in.

LICENSE: LGPL

CHANGELOG:

* dlls/msvcrt: main.c, cppexcept.c: Alberto Massari <alby@exln.com>
- allow MSVC C++ apps to reraise exceptions without infinite recursion
  in the exception handlers.

-- 
gmt

"War is an ugly thing, but not the ugliest of things;
the decayed and degraded state of moral and patriotic
feeling which thinks that nothing is worth war is much
worse. A man who has nothing for which he is willing
to fight; nothing he cares about more than his own
personal safety; is a miserable creature who has no
chance of being free, unless made and kept so by the
exertions of better persons than himself."

-- John Stuart Mill
diff -ur -x CVS -x 'bigdif*' ../wine.test/dlls/msvcrt/cppexcept.c ./dlls/msvcrt/cppexcept.c
--- ../wine.test/dlls/msvcrt/cppexcept.c	2002-10-31 20:13:49.000000000 -0600
+++ ./dlls/msvcrt/cppexcept.c	2002-11-12 22:06:11.000000000 -0600
@@ -176,6 +176,10 @@
 {
     int i;
 
+    if(type==NULL)
+        return;
+
+
     DPRINTF( "exception type:\n" );
     DPRINTF( "flags %x destr %p handler %p type info %p\n",
              type->flags, type->destructor, type->custom_handler, type->type_info_table );
@@ -240,6 +244,10 @@
 {
     UINT i;
 
+    if(exc_type==NULL || exc_type->type_info_table==NULL)
+        return NULL;
+
+
     for (i = 0; i < exc_type->type_info_table->count; i++)
     {
         cxx_type_info *type = exc_type->type_info_table->info[i];
@@ -304,13 +312,13 @@
             MSVCRT_terminate();
         }
         handler = descr->unwind_table[trylevel].handler;
+	trylevel = descr->unwind_table[trylevel].prev;
         if (handler)
         {
             TRACE( "calling unwind handler %p trylevel %d last %d ebp %p\n",
                    handler, trylevel, last_level, &frame->ebp );
             call_ebp_func( handler, &frame->ebp );
         }
-        trylevel = descr->unwind_table[trylevel].prev;
     }
     frame->trylevel = last_level;
 }
@@ -447,6 +455,8 @@
         rec = msvcrt_get_thread_data()->exc_record;
         exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
     }
+    else if (exc_type->custom_handler)
+        return exc_type->custom_handler( rec, frame, exc_context, dispatch, descr, 0, 0, 0 );
 
     if (TRACE_ON(seh))
     {
@@ -481,6 +491,8 @@
 
 #endif  /* __i386__ */
 
+extern DWORD LastExceptionObj_tls_index, LastExceptionType_tls_index;
+
 /*********************************************************************
  *		_CxxThrowException (MSVCRT.@)
  */
@@ -488,6 +500,17 @@
 {
     DWORD args[3];
 
+    if(object==NULL && type==NULL)
+    {
+        object=TlsGetValue(LastExceptionObj_tls_index);
+        type=(cxx_exception_type*)TlsGetValue(LastExceptionType_tls_index);
+    }
+    else
+    {
+        TlsSetValue(LastExceptionObj_tls_index,object);
+        TlsSetValue(LastExceptionType_tls_index,type);
+    }
+
     args[0] = CXX_FRAME_MAGIC;
     args[1] = (DWORD)object;
     args[2] = (DWORD)type;
diff -ur -x CVS -x 'bigdif*' ../wine.test/dlls/msvcrt/main.c ./dlls/msvcrt/main.c
--- ../wine.test/dlls/msvcrt/main.c	2002-11-04 21:30:27.000000000 -0600
+++ ./dlls/msvcrt/main.c	2002-11-12 22:01:55.000000000 -0600
@@ -29,6 +29,10 @@
 /* Index to TLS */
 DWORD MSVCRT_tls_index;
 
+/* TLS for re-throwing exceptions */
+DWORD LastExceptionObj_tls_index;
+DWORD LastExceptionType_tls_index;
+
 static inline BOOL msvcrt_init_tls(void);
 static inline BOOL msvcrt_free_tls(void);
 const char* msvcrt_get_reason(DWORD reason) WINE_UNUSED;
@@ -91,6 +95,21 @@
     ERR("TlsAlloc() failed!\n");
     return FALSE;
   }
+
+  LastExceptionObj_tls_index=TlsAlloc();
+  if (LastExceptionObj_tls_index == TLS_OUT_OF_INDEXES)
+  {
+    ERR("TlsAlloc() failed!\n");
+    return FALSE;
+  }
+
+  LastExceptionType_tls_index=TlsAlloc();
+  if(LastExceptionType_tls_index == TLS_OUT_OF_INDEXES)
+  {
+    ERR("TlsAlloc() failed!\n");
+    return FALSE;
+  }
+
   return TRUE;
 }
 
@@ -101,6 +120,16 @@
     ERR("TlsFree() failed!\n");
     return FALSE;
   }
+  if (!TlsFree(LastExceptionObj_tls_index))
+  {
+    ERR("TlsFree() failed!\n");
+    return FALSE;
+  }
+  if (!TlsFree(LastExceptionType_tls_index))
+  {
+    ERR("TlsFree() failed!\n");
+    return FALSE;
+  }
   return TRUE;
 }
 

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux