widl [2/5]: Output working exception handling macros.

Dan Hipschman dsh at linux.ucla.edu
Mon Nov 19 20:26:28 CST 2007


This patches WIDL so it outputs exception handling macros for Wine in the
proxy / stub files.  The result ends up looking like this:

#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 (__wine_handle_page_fault_gracefully(rec))
        return ExceptionContinueExecution;
    wef->rec = *rec;
    if (rec->ExceptionFlags & wef->mask)
        return ExceptionContinueSearch;
    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 |   91 ++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/widl/typegen.h |    1 +
 5 files changed, 103 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..ce647e7 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,88 @@ 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 (__wine_handle_page_fault_gracefully(rec))\n");
+    print_file(file, 2, "return ExceptionContinueExecution;\n");
+    print_file(file, 1, "wef->rec = *rec;\n");
+    print_file(file, 1, "if (rec->ExceptionFlags & wef->mask)\n");
+    print_file(file, 2, "return ExceptionContinueSearch;\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