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