seh_try_macros2-00

Gregory M. Turner gmturner007 at ameritech.net
Wed May 14 22:08:20 CDT 2003


This should not go in, it's WIP, just trolling for comments...

License: Bugroff

Changelog: 
  
  - include/wine/excpetion.h
  - memory/global.c

  Implement gcc-specific "__TYPED_TRY" macro supposedly capable of
  intercepting return and running the finally clause.  If it compiles,
  it should work on x86... If it fails to compile, it needs you to specify
  the return type as in 

    __TYPED_TRY(float) { 
    } __FINALLY(func) { 
    } __ENDTRY

. Other arches may have much less success ;) of course, almost any problem
  of this kind should be fixed by turning __TRY into the appropriate
  __TYPED_TRY.  __TRY generates warnings, some may be fixable.

Untested, and probably broken... but this should give you an idea 
of where I'm headed.  From here, I can probably implement __try and friends
much as before, with the twist that __try is just __typed_try(int ****) or
what-have-you.

-gmt

--
diff -ur --minimal --exclude-from=/home/greg/bin/winetreediff_excl ../wine.vanilla/include/wine/exception.h ./include/wine/exception.h
--- ../wine.vanilla/include/wine/exception.h	2003-01-29 21:50:14.000000000 -0600
+++ ./include/wine/exception.h	2003-05-14 21:37:51.000000000 -0500
@@ -74,6 +74,94 @@
 
 #else  /* USE_COMPILER_EXCEPTIONS */
 
+#if defined(__GNUC__)
+
+#define __TYPED_TRY(return_type) \
+    if ( ({ \
+        __label__ __typed_try_block_setup, __typed_try_block_entry, \
+	          __typed_try_block_exit_no_return, __typed_try_block_exit_return0, \
+		  __typed_try_block_exit_return1, __typed_try_block_exit_full; \
+	__WINE_FRAME __wf; \
+	typeof(return_type)  __scope_return_val; \
+        auto typeof(return_type) __scope_tryblock_fn(); \
+        goto __typed_try_block_setup; \
+	\
+        __typed_try_block_entry: \
+	__scope_return_val = __scope_tryblock_fn(); \
+	__wine_pop_frame( &__wf.frame ); \
+	goto __typed_try_block_exit_return0; \
+	\
+	__typed_try_block_exit_return1: \
+        return __scope_return_val; \
+        \
+        typeof(return_type) __scope_tryblock_fn() \
+        { \
+	    { 
+
+#define __TRY __TYPED_TRY(unsigned int ****)
+
+#define __FINALLY(func) \
+            } \
+            /* this unwinds the __scope_tryblock_fn call */ \
+	    goto __typed_try_block_exit_no_return; \
+        } \
+	\
+        __typed_try_block_setup: \
+        __wf.frame.Handler = (PEXCEPTION_HANDLER)__wine_finally_handler; \
+        __wf.u.finally_func = (func); \
+        __wine_push_frame( &__wf.frame ); \
+        goto __typed_try_block_entry; \
+	\
+	__typed_try_block_exit_return0: \
+	(func)(1); \
+	goto __typed_try_block_exit_return1; \
+	\
+	__typed_try_block_exit_no_return: \
+	__wine_pop_frame( &__wf.frame ); \
+	(func)(1); \
+	{ \
+	    {
+
+#define __EXCEPT(func) \
+            } \
+            /* this unwinds the __scope_tryblock_fn call */ \
+	    goto __typed_try_block_exit_no_return; \
+        } \
+	\
+        __typed_try_block_exit_return0: \
+        goto __typed_try_block_exit_return1; \
+	\
+        __typed_try_block_exit_no_return: \
+        __wine_pop_frame( &__wf.frame ); \
+	goto __typed_try_block_exit_full; \
+	\
+	__typed_try_block_setup: \
+        __wf.frame.Handler = (PEXCEPTION_HANDLER)__wine_exception_handler; \
+        __wf.u.filter = (func); \
+        __wine_push_frame( &__wf.frame ); \
+        if (!(setjmp( __wf.jmp ))) { \
+	    goto __typed_try_block_entry; \
+	} else { \
+            const __WINE_FRAME * const __eptr WINE_UNUSED = &__wf; \
+	    {
+
+#define __ENDTRY \
+            } \
+	} \
+	__typed_try_block_exit_full: 0; \
+    }) ) { } else { }
+
+#define __BREAK goto __typed_try_block_exit_no_return
+
+#else /* __GNUC__ */
+
+/* these are the old wine __TRY macros.  They are not
+ * capable of intercepting returns, which means the 
+ * return-from-tryblock feature of the above macros
+ * shouldn't be used in parts of wine which will be used
+ * with non-gcc compilers. 
+ */
+
 #define __TRY \
     do { __WINE_FRAME __f; \
          int __first = 1; \
@@ -81,6 +169,8 @@
          { \
              do {
 
+#define __TYPED_TRY(x) __TRY
+
 #define __EXCEPT(func) \
              } while(0); \
              __wine_pop_frame( &__f.frame ); \
@@ -114,6 +204,9 @@
          } \
     } while (0);
 
+#define __BREAK break
+
+#endif /* __GNUC__*/
 
 typedef DWORD (CALLBACK *__WINE_FILTER)(PEXCEPTION_POINTERS);
 typedef void (CALLBACK *__WINE_FINALLY)(BOOL);
diff -ur --minimal --exclude-from=/home/greg/bin/winetreediff_excl ../wine.vanilla/memory/global.c ./memory/global.c
--- ../wine.vanilla/memory/global.c	2003-05-14 15:06:26.000000000 -0500
+++ ./memory/global.c	2003-05-14 21:38:13.000000000 -0500
@@ -1251,7 +1251,7 @@
         if (ISPOINTER(pmem)) {
             if (HeapValidate( GetProcessHeap(), 0, pmem )) {
                 handle = (HGLOBAL)pmem;  /* valid fixed block */
-                break;
+                __BREAK;
             }
             handle = POINTER_TO_HANDLE(pmem);
         } else
@@ -1263,7 +1263,7 @@
             test = maybe_intern->Pointer;
             if (HeapValidate( GetProcessHeap(), 0, (char *)test - HGLOBAL_STORAGE ) && /* obj(-handle) valid arena? */
                 HeapValidate( GetProcessHeap(), 0, maybe_intern ))  /* intern valid arena? */
-                break;  /* valid moveable block */
+                __BREAK;  /* valid moveable block */
         }
         handle = 0;
         SetLastError( ERROR_INVALID_HANDLE );
-- 
"There is no dignity quite so impressive, and no independence quite
so important, as living within your means." --Calvin Coolidge

gmt



More information about the wine-devel mailing list