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