widl [1/7]: Output working exception handling macros. [take 3]

Dan Hipschman dsh at linux.ucla.edu
Wed Nov 28 19:21:58 CST 2007


In this revision, I leave setting permissions on page faults to the
unhandled exception filter and simply ignore page faults on execution
access (read access exceptions should be caught since they translate
into bad stub data, but these don't pose a problem anyway).  I also
fixed a bug regarding how the mask field of __widl_except_frame was
set.

All the other patches in this set are the same as before (only updated
to reflect some recent changes to ole32).  The whole patch set was
regression tested with winetest and nothing new fails.

Here's what the output looks like:

#ifdef __WINESRC__
#include <winternl.h>
#include "wine/exception.h"

#undef RpcExceptionCode
#undef RpcTryExcept
#undef RpcExcept
#undef RpcEndExcept
#undef RpcTryFinally
#undef RpcFinally
#undef RpcEndFinally

#if !defined(__GNUC__) && !defined(__attribute__)
#define __attribute__(x)
#endif

typedef struct
{
    EXCEPTION_REGISTRATION_RECORD frame;
    EXCEPTION_RECORD rec;
    sigjmp_buf jmp;
    DWORD mask;
} __widl_except_frame_t;

static DWORD __widl_exception_handler(
    EXCEPTION_RECORD *rec,
    EXCEPTION_REGISTRATION_RECORD *frame,
    CONTEXT *context __attribute__((unused)),
    EXCEPTION_REGISTRATION_RECORD **pdispatcher __attribute__((unused)))
{
    __widl_except_frame_t *wef = (__widl_except_frame_t *) frame;
    if ((rec->ExceptionFlags & wef->mask)
        || (rec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION
            && 2 <= rec->NumberParameters
            && rec->ExceptionInformation[0] == EXCEPTION_EXECUTE_FAULT))
        return ExceptionContinueSearch;
    wef->rec = *rec;
    RtlUnwind(frame, 0, rec, 0);
    siglongjmp(wef->jmp, 1);
}

#define RpcExceptionCode() (__f.rec.ExceptionCode)

#define RpcTryExcept \
    { \
        int __need_pop = 1; \
        __widl_except_frame_t __f; \
        __f.frame.Handler = __widl_exception_handler; \
        __f.mask = EH_UNWINDING | EH_EXIT_UNWIND | EH_NESTED_CALL; \
        __wine_push_frame(&__f.frame); \
        if (!sigsetjmp(__f.jmp, 1)) \
        {
#define RpcExcept(cond) \
        } \
        else \
        { \
            __wine_pop_frame(&__f.frame); \
            __need_pop = 0; \
            if (cond) \
            {
#define RpcEndExcept \
            } \
            else \
                RtlRaiseException(&__f.rec); \
        } \
        if (__need_pop) \
            __wine_pop_frame(&__f.frame); \
    }

#define RpcTryFinally \
    { \
        int __ok = 0; \
        __widl_except_frame_t __f; \
        __f.frame.Handler = __widl_exception_handler; \
        __f.mask = ~(EH_UNWINDING | EH_EXIT_UNWIND); \
        __wine_push_frame(&__f.frame); \
        if (!sigsetjmp(__f.jmp, 1)) \
        {
#define RpcFinally \
            __ok = 1; \
        } \
        __wine_pop_frame(&__f.frame); \
        {
#define RpcEndFinally \
        } \
        if (!__ok) \
            RtlRaiseException(&__f.rec); \
    }

#endif  /* __WINESRC__ */


---
 tools/widl/client.c  |    7 ++++
 tools/widl/proxy.c   |    3 ++
 tools/widl/server.c  |    1 +
 tools/widl/typegen.c |   92 ++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/widl/typegen.h |    1 +
 5 files changed, 104 insertions(+), 0 deletions(-)

diff --git a/tools/widl/client.c b/tools/widl/client.c
index 696dd83..d944ab0 100644
--- a/tools/widl/client.c
+++ b/tools/widl/client.c
@@ -141,6 +141,12 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
         print_client("MIDL_STUB_MESSAGE _StubMsg;\n");
         fprintf(client, "\n");
 
+        if (!is_void(def->type))
+        {
+            print_client("/* Silence warnings about being used uninitialized.  */\n");
+            print_client("memset(&_RetVal, 0, sizeof _RetVal);\n\n");
+        }
+
         /* check pointers */
         check_pointers(func);
 
@@ -380,6 +386,7 @@ static void init_client(void)
     fprintf(client, "\n");
     print_client("#include \"%s\"\n", header_name);
     fprintf(client, "\n");
+    write_exception_macros(client);
 }
 
 
diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c
index 8a81885..45f312a 100644
--- a/tools/widl/proxy.c
+++ b/tools/widl/proxy.c
@@ -110,6 +110,7 @@ static void init_proxy(ifref_list_t *ifaces)
   print_proxy( "\n");
   print_proxy( "#include \"%s\"\n", header_name);
   print_proxy( "\n");
+  write_exception_macros(proxy);
   write_formatstringsdecl(proxy, indent, ifaces, need_proxy);
   write_stubdescproto();
 }
@@ -271,6 +272,8 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
   print_proxy( "\n");
 
   /* FIXME: trace */
+  print_proxy( "/* Silence warnings about being used uninitialized.  */\n" );
+  print_proxy( "memset(&_RetVal, 0, sizeof _RetVal);\n\n" );
   clear_output_vars( cur->args );
 
   print_proxy( "RpcTryExcept\n" );
diff --git a/tools/widl/server.c b/tools/widl/server.c
index c915662..3ae3f6a 100644
--- a/tools/widl/server.c
+++ b/tools/widl/server.c
@@ -392,6 +392,7 @@ static void init_server(void)
     fprintf(server, "\n");
     print_server("#include \"%s\"\n", header_name);
     fprintf(server, "\n");
+    write_exception_macros(server);
 }
 
 
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 1078ede..5b1e92e 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -54,6 +54,7 @@ struct expr_eval_routine
     const expr_t *expr;
 };
 
+static inline int is_base_type(unsigned char type);
 static size_t fields_memsize(const var_list_t *fields, unsigned int *align);
 static size_t write_struct_tfs(FILE *file, type_t *type, const char *name, unsigned int *tfsoff);
 static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type,
@@ -339,6 +340,11 @@ void write_parameters_init(FILE *file, int indent, const func_t *func)
             print_file(file, indent, "MIDL_memset(&%s, 0, sizeof %s);\n", n, n);
         else if (is_ptr(t) || is_array(t))
             print_file(file, indent, "%s = 0;\n", n);
+        else
+        {
+            assert(is_base_type(t->type));
+            print_file(file, indent, "%s = 0;  /* Avoid initialization warnings.  */\n", n);
+        }
     }
 
     fprintf(file, "\n");
@@ -3235,3 +3241,89 @@ void write_endpoints( FILE *f, const char *prefix, const str_list_t *list )
 error:
     error("Invalid endpoint syntax '%s'\n", endpoint->str);
 }
+
+void write_exception_macros(FILE *file)
+{
+    print_file(file, 0, "#ifdef __WINESRC__\n");
+    print_file(file, 0, "#include <winternl.h>\n");
+    print_file(file, 0, "#include \"wine/exception.h\"\n\n");
+    print_file(file, 0, "#undef RpcExceptionCode\n");
+    print_file(file, 0, "#undef RpcTryExcept\n");
+    print_file(file, 0, "#undef RpcExcept\n");
+    print_file(file, 0, "#undef RpcEndExcept\n");
+    print_file(file, 0, "#undef RpcTryFinally\n");
+    print_file(file, 0, "#undef RpcFinally\n");
+    print_file(file, 0, "#undef RpcEndFinally\n\n");
+    print_file(file, 0, "#if !defined(__GNUC__) && !defined(__attribute__)\n");
+    print_file(file, 0, "#define __attribute__(x)\n");
+    print_file(file, 0, "#endif\n\n");
+    print_file(file, 0, "typedef struct\n");
+    print_file(file, 0, "{\n");
+    print_file(file, 1, "EXCEPTION_REGISTRATION_RECORD frame;\n");
+    print_file(file, 1, "EXCEPTION_RECORD rec;\n");
+    print_file(file, 1, "sigjmp_buf jmp;\n");
+    print_file(file, 1, "DWORD mask;\n");
+    print_file(file, 0, "} __widl_except_frame_t;\n\n");
+    print_file(file, 0, "static DWORD __widl_exception_handler(\n");
+    print_file(file, 1, "EXCEPTION_RECORD *rec,\n");
+    print_file(file, 1, "EXCEPTION_REGISTRATION_RECORD *frame,\n");
+    print_file(file, 1, "CONTEXT *context __attribute__((unused)),\n");
+    print_file(file, 1, "EXCEPTION_REGISTRATION_RECORD **pdispatcher __attribute__((unused)))\n");
+    print_file(file, 0, "{\n");
+    print_file(file, 1, "__widl_except_frame_t *wef = (__widl_except_frame_t *) frame;\n");
+    print_file(file, 1, "if ((rec->ExceptionFlags & wef->mask)\n");
+    print_file(file, 1, "    || (rec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION\n");
+    print_file(file, 1, "        && 2 <= rec->NumberParameters\n");
+    print_file(file, 1, "        && rec->ExceptionInformation[0] == EXCEPTION_EXECUTE_FAULT))\n");
+    print_file(file, 2, "return ExceptionContinueSearch;\n");
+    print_file(file, 1, "wef->rec = *rec;\n");
+    print_file(file, 1, "RtlUnwind(frame, 0, rec, 0);\n");
+    print_file(file, 1, "siglongjmp(wef->jmp, 1);\n");
+    print_file(file, 0, "}\n\n");
+    print_file(file, 0, "#define RpcExceptionCode() (__f.rec.ExceptionCode)\n\n");
+    print_file(file, 0, "#define RpcTryExcept \\\n");
+    print_file(file, 1, "{ \\\n");
+    print_file(file, 2, "int __need_pop = 1; \\\n");
+    print_file(file, 2, "__widl_except_frame_t __f; \\\n");
+    print_file(file, 2, "__f.frame.Handler = __widl_exception_handler; \\\n");
+    print_file(file, 2, "__f.mask = EH_UNWINDING | EH_EXIT_UNWIND | EH_NESTED_CALL; \\\n");
+    print_file(file, 2, "__wine_push_frame(&__f.frame); \\\n");
+    print_file(file, 2, "if (!sigsetjmp(__f.jmp, 1)) \\\n");
+    print_file(file, 2, "{\n");
+    print_file(file, 0, "#define RpcExcept(cond) \\\n");
+    print_file(file, 2, "} \\\n");
+    print_file(file, 2, "else \\\n");
+    print_file(file, 2, "{ \\\n");
+    print_file(file, 3, "__wine_pop_frame(&__f.frame); \\\n");
+    print_file(file, 3, "__need_pop = 0; \\\n");
+    print_file(file, 3, "if (cond) \\\n");
+    print_file(file, 3, "{\n");
+    print_file(file, 0, "#define RpcEndExcept \\\n");
+    print_file(file, 3, "} \\\n");
+    print_file(file, 3, "else \\\n");
+    print_file(file, 4, "RtlRaiseException(&__f.rec); \\\n");
+    print_file(file, 2, "} \\\n");
+    print_file(file, 2, "if (__need_pop) \\\n");
+    print_file(file, 3, "__wine_pop_frame(&__f.frame); \\\n");
+    print_file(file, 1, "}\n\n");
+    print_file(file, 0, "#define RpcTryFinally \\\n");
+    print_file(file, 1, "{ \\\n");
+    print_file(file, 2, "int __ok = 0; \\\n");
+    print_file(file, 2, "__widl_except_frame_t __f; \\\n");
+    print_file(file, 2, "__f.frame.Handler = __widl_exception_handler; \\\n");
+    print_file(file, 2, "__f.mask = ~(EH_UNWINDING | EH_EXIT_UNWIND); \\\n");
+    print_file(file, 2, "__wine_push_frame(&__f.frame); \\\n");
+    print_file(file, 2, "if (!sigsetjmp(__f.jmp, 1)) \\\n");
+    print_file(file, 2, "{\n");
+    print_file(file, 0, "#define RpcFinally \\\n");
+    print_file(file, 3, "__ok = 1; \\\n");
+    print_file(file, 2, "} \\\n");
+    print_file(file, 2, "__wine_pop_frame(&__f.frame); \\\n");
+    print_file(file, 2, "{\n");
+    print_file(file, 0, "#define RpcEndFinally \\\n");
+    print_file(file, 2, "} \\\n");
+    print_file(file, 2, "if (!__ok) \\\n");
+    print_file(file, 3, "RtlRaiseException(&__f.rec); \\\n");
+    print_file(file, 1, "}\n\n");
+    print_file(file, 0, "#endif  /* __WINESRC__ */\n\n");
+}
diff --git a/tools/widl/typegen.h b/tools/widl/typegen.h
index c9a5148..4e44663 100644
--- a/tools/widl/typegen.h
+++ b/tools/widl/typegen.h
@@ -60,3 +60,4 @@ void print(FILE *file, int indent, const char *format, va_list ap);
 int get_padding(const var_list_t *fields);
 int is_user_type(const type_t *t);
 expr_t *get_size_is_expr(const type_t *t, const char *name);
+void write_exception_macros(FILE *file);



More information about the wine-patches mailing list