seh_try_macros-03.diff

Greg Turner gmturner007 at ameritech.net
Mon Jan 13 20:00:39 CST 2003


At this point, 

I've made quite a mess of some of these files w.r.t.
indentation (I'm a two-spaces guy, but the authors of
some files I'm changing use four). Will fix in 
seh_try_macros-NOOP-04.diff.

After that, I guess I'm done with SEH for now until I figure
out what to do about re-raising in __finally.

LICENSE: X11/Bugroff
CHANGELOG:
* dlls/ntdll: exception.c, ntdll.spec;
  dlls/ntdll/tests: seh_macros.c;
  include/wine: exception.h:
  Greg Turner <gmturner007 at ameritech.net>
- Fix a broken test, and avoid compiler-optimization bugs
  (hopefully exposed only by the trivial nature of the test code)
  that allowed the test to pass previously.
- some "performance" improvements (from slower to slow).
- add __leave support and some tests.

--
diff -ur -x CVS -x 'bigdif*' -x autom4te.cache ../wine.test/dlls/ntdll/exception.c ./dlls/ntdll/exception.c
--- ../wine.test/dlls/ntdll/exception.c	2003-01-13 19:29:54.000000000 -0600
+++ ./dlls/ntdll/exception.c	2003-01-13 19:31:39.000000000 -0600
@@ -67,7 +67,7 @@
 wine_seh_f_data *wine_SEH_FData;
 static DWORD wine_seh_f_tls_index = -1;
 
-void wine_init_thread_seh_f()
+inline void wine_init_thread_seh_f()
 {
     if (wine_seh_f_tls_index == -1)
         if ((wine_seh_f_tls_index = TlsAlloc()) == -1) assert(FALSE);
@@ -106,6 +106,12 @@
     return wine_SEH_FData->stackdata[--wine_SEH_FData->stackdepth];
 }
 
+void __wine_inc_seh_f_loop()
+{
+    wine_init_thread_seh_f();
+    wine_SEH_FData->loop++;
+}
+
 extern void SIGNAL_Unblock(void);
 
 void WINAPI EXC_RtlRaiseException( PEXCEPTION_RECORD, PCONTEXT );
diff -ur -x CVS -x 'bigdif*' -x autom4te.cache ../wine.test/dlls/ntdll/ntdll.spec ./dlls/ntdll/ntdll.spec
--- ../wine.test/dlls/ntdll/ntdll.spec	2003-01-13 19:29:54.000000000 -0600
+++ ./dlls/ntdll/ntdll.spec	2003-01-13 17:24:50.000000000 -0600
@@ -1031,6 +1031,7 @@
 @ cdecl -norelay __wine_exception_handler(ptr ptr ptr ptr) __wine_exception_handler
 @ cdecl -norelay __wine_finally_handler(ptr ptr ptr ptr) __wine_finally_handler
 @ cdecl -norelay __wine_get_seh_f_loop() __wine_get_seh_f_loop
+@ cdecl -norelay __wine_inc_seh_f_loop() __wine_inc_seh_f_loop
 @ cdecl -norelay __wine_set_seh_f_loop(long) __wine_set_seh_f_loop
 @ cdecl -norelay __wine_push_seh_f_reraise(long) __wine_push_seh_f_reraise
 @ cdecl -norelay __wine_pop_seh_f_reraise() __wine_pop_seh_f_reraise
diff -ur -x CVS -x 'bigdif*' -x autom4te.cache ../wine.test/dlls/ntdll/tests/seh_macros.c ./dlls/ntdll/tests/seh_macros.c
--- ../wine.test/dlls/ntdll/tests/seh_macros.c	2003-01-13 19:29:54.000000000 -0600
+++ ./dlls/ntdll/tests/seh_macros.c	2003-01-13 19:37:15.000000000 -0600
@@ -29,6 +29,17 @@
 {
     int x;
 
+    /*
+     * this macro should be quieter than assert(), although the finally() process still
+     * generates asserts, ATM.  Once that is fixed the test should be silent.
+     */
+    #define CRASH_OUT \
+      \
+      if (x) /* I think this branch stops gcc from performing optimizations that break some tests */ \
+        x += (int)(*(int **)0); \
+      else \
+        x -= (int)(*(int **)0);
+
     trace("beginning TryMacros:\n");
     trace("  basic no-exception-handling macro test\n");
 
@@ -44,9 +55,9 @@
     x = 0;
     __try {
       x++;
-      x = (int)(*(int **)0);
-      x++; /* never executed */
-    } __except( ( (x==1) ? ( ok(FALSE, "x should be 1 was %d",x) ) : (x=3) ), 1) {
+      CRASH_OUT;
+      x++;
+    } __except( ( (x!=1) ? ( ok(FALSE, "x should be 1 was %d",x) ) : (x=3) ), 1) {
       ok((x==3), "x should be 3 was %d", x);
       if (x==3) x = 4;
     }
@@ -64,7 +75,7 @@
       } __except(0) {
         ok(FALSE, "exception handler code shouldn't run");
 	x = -99;
-	assert(FALSE);
+	CRASH_OUT;
       }
       ok((x==2), "x should be 2 was %d", x);
       if (x==2) x = 3;
@@ -82,11 +93,11 @@
       __try {
         ok((x==0), "x should be 0 was %d", x);
 	if (x==0) x = 1;
-	assert(FALSE);
+	CRASH_OUT;
       } __except(1) {
         ok((x==1), "x should be 1 was %d", x);
 	if (x==1) x = 2;
-	assert(FALSE);
+	CRASH_OUT;
       }
       ok(FALSE, "this code should be skipped");
     } __except(1) {
@@ -95,7 +106,7 @@
       __try {
         ok ((x==3), "x should be 3 was %d", x);
 	if (x==3) x = 4;
-	assert(FALSE);
+	CRASH_OUT;
       } __except(1) {
         ok ((x==4), "x should be 4 was %d", x);
 	if (x==4) x = 5;
@@ -128,13 +139,13 @@
     trace("  absurdly nested exceptions test: some exceptions\n");
 
     x = 0;
-    #define nesttry1(x) __try {x++; } __except(1) { x++; assert(FALSE); }          
-    #define nesttry2(x) __try {x++; nesttry1(x) } __except(1) { x++; nesttry1(x); assert(FALSE); }
-    #define nesttry3(x) __try {x++; nesttry2(x) } __except(1) { x++; nesttry2(x); assert(FALSE); }
-    #define nesttry4(x) __try {x++; nesttry3(x) } __except(1) { x++; nesttry3(x); assert(FALSE); }
-    #define nesttry5(x) __try {x++; nesttry4(x) } __except(1) { x++; nesttry4(x); assert(FALSE); }
-    #define nesttry6(x) __try {x++; nesttry5(x) } __except(1) { x++; nesttry5(x); assert(FALSE); }
-    #define nesttry7(x) __try {x++; nesttry6(x); assert(FALSE); } __except(1) { x++; nesttry6(x); assert(FALSE); } 
+    #define nesttry1(x) __try {x++; } __except(1) { x++; CRASH_OUT; }          
+    #define nesttry2(x) __try {x++; nesttry1(x) } __except(1) { x++; nesttry1(x); CRASH_OUT; }
+    #define nesttry3(x) __try {x++; nesttry2(x) } __except(1) { x++; nesttry2(x); CRASH_OUT; }
+    #define nesttry4(x) __try {x++; nesttry3(x) } __except(1) { x++; nesttry3(x); CRASH_OUT; }
+    #define nesttry5(x) __try {x++; nesttry4(x) } __except(1) { x++; nesttry4(x); CRASH_OUT; }
+    #define nesttry6(x) __try {x++; nesttry5(x) } __except(1) { x++; nesttry5(x); CRASH_OUT; }
+    #define nesttry7(x) __try {x++; nesttry6(x); CRASH_OUT; } __except(1) { x++; nesttry6(x); CRASH_OUT; } 
     __try {
       nesttry7(x)
     } __except (1) {
@@ -174,7 +185,7 @@
     __try {
       __try {
         x++;
-	assert(FALSE);
+	CRASH_OUT;
         x++;
       } __finally {
         ok((x==1), "x should be 1 was %d", x);
@@ -215,7 +226,7 @@
         __try {
 	  ok((x==2), "x should be 2 was %d", x);
 	  if (x==2) x = 3;
-	  assert(FALSE);
+	  CRASH_OUT;
 	  ok(FALSE, "this code should not execute");
 	} __finally {
 	  ok((x==3), "x should be 3 was %d", x);
@@ -249,7 +260,7 @@
 	  ok((x==3), "x should be 3 was %d", x);
 	  if (x==3) x = 4;
 	}
-	assert(FALSE);
+	CRASH_OUT;
 	ok(FALSE, "this code should not execute");
       } __finally {
         ok((x==4), "x should be 4 was %d", x);
@@ -262,7 +273,57 @@
     }
     ok((x==6), "x should be 6 was %d", x);
 
- 
+    trace("  absurdly nested maze of try/finally clauses\n");
+
+    #define tryfinallymaze0(x) __try { x++; CRASH_OUT; } __finally { x++; }
+    #define tryfinallymaze1(x) __try { x++; tryfinallymaze0(x); } __except(1) { tryfinallymaze0(x); x++; }
+    #define tryfinallymaze2(x) __try { tryfinallymaze1(x); x++; } __finally { tryfinallymaze1(x); x++; CRASH_OUT; }
+    #define tryfinallymaze3(x) __try { tryfinallymaze2(x); x++; } __except(1) { tryfinallymaze2(x); }
+    #define tryfinallymaze4(x) __try { tryfinallymaze3(x); x++; } __finally { tryfinallymaze3(x); x++; CRASH_OUT; }
+    #define tryfinallymaze5(x) __try { tryfinallymaze4(x); x++; } __except(1) { tryfinallymaze4(x); }
+    #define tryfinallymaze6(x) __try { tryfinallymaze5(x); x++; } __finally { tryfinallymaze5(x); x++; CRASH_OUT; }
+    #define tryfinallymaze7(x) __try { tryfinallymaze6(x); x++; } __except(1) { x++; }
+
+    x = 0;
+
+    tryfinallymaze7(x)
+
+    ok((x==161), "x should be 161 was %d", x);
+
+    #undef tryfinallymaze7
+    #undef tryfinallymaze6
+    #undef tryfinallymaze5
+    #undef tryfinallymaze4
+    #undef tryfinallymaze3
+    #undef tryfinallymaze2
+    #undef tryfinallymaze1
+    #undef tryfinallymaze0
+
+    trace("  test of the __leave macro in a __try/__except clause\n");
+
+    x = 0;
+    __try {
+      x = 1;
+      __leave;
+      x = 2;
+    } __except(1) {
+      x = 3;
+    }
+    ok((x==1), "x should be 1 was %d",x);
+
+    trace("  test of the __leave macro in a __try/__finally clause\n");
+    
+    x = 0;
+    __try {
+      x = 1;
+      __leave;
+      x = 2;
+    } __finally {
+      ok((x==1), "x should be 1 was %d",x);
+      if (x==1) x = 3;
+    }
+    ok((x==3), "x should be 3 was %d", x);
+
     trace("End.\n");
 }
 
diff -ur -x CVS -x 'bigdif*' -x autom4te.cache ../wine.test/include/wine/exception.h ./include/wine/exception.h
--- ../wine.test/include/wine/exception.h	2003-01-13 19:29:54.000000000 -0600
+++ ./include/wine/exception.h	2003-01-13 16:49:56.000000000 -0600
@@ -160,20 +160,26 @@
 /* these functions simultate a global thread-local variable */
 extern int __wine_get_seh_f_loop(); 
 extern void __wine_set_seh_f_loop(int);
+extern void __wine_inc_seh_f_loop();
 /* these functions implement a TLS stack of elements (currently int's). */
 /* FIXME: push/pop an exception info struct instead of an int */
 extern int __wine_pop_seh_f_reraise();
 extern void __wine_push_seh_f_reraise(int);
 
+#ifndef __NO_VC_SEH_MACROS__
+
 #define __try \
   \
   if ( ({ \
+    __label__ __leavelabel; \
     int seh_result = -2; \
     static WINE_EXCEPTION_FILTER(seh_handler); \
     __TRY {
 
 #define __finally \
-    \
+        \
+        __leavelabel: \
+	if (0) { goto __leavelabel; } /* appease compiler */ \
     } __EXCEPT(seh_handler) { \
     } __ENDTRY \
     WINE_EXCEPTION_FILTER(seh_handler) { \
@@ -184,8 +190,7 @@
     } \
     if (seh_result != -4) __wine_push_seh_f_reraise(0); \
   0; }) ) { } else \
-    /* FIXME: this could be done more efficiently */ \
-    for (__wine_set_seh_f_loop(0); __wine_get_seh_f_loop() <= 1; __wine_set_seh_f_loop(__wine_get_seh_f_loop() + 1)) \
+    for (__wine_set_seh_f_loop(0); __wine_get_seh_f_loop() <= 1; __wine_inc_seh_f_loop() ) \
       if (__wine_get_seh_f_loop() == 1) { \
         if (__wine_pop_seh_f_reraise()) { \
           /* FIXME: re-raise from stored exception info */ assert(FALSE); \
@@ -195,7 +200,9 @@
       } else
 
 #define __except(...) \
-   \
+      \
+      __leavelabel: \
+      if (0) { goto __leavelabel; } /* appease compiler */ \
     } __EXCEPT(seh_handler) { \
       seh_result = -3; \
     } __ENDTRY \
@@ -205,8 +212,11 @@
     } \
   (seh_result != -3); }) ) { } else
 
-/* FIXME */
-#define __leave assert(FALSE)
+#define __leave \
+  \
+  goto __leavelabel
+
+#endif /* NO_VC_SEH_MACROS */
 
 #endif /* USE_COMPILER_EXCEPTIONS */
 
-- 
gmt

p.s., note: the newline between the #endif and the "--\ngmt" is part of the .diff.

"If everyone is thinking alike then somebody isn't
thinking." --George S. Patton




More information about the wine-patches mailing list