widl: Make the exception handling macros more general and use the same code everywhere.

This commit is contained in:
Alexandre Julliard 2008-09-15 14:05:26 +02:00
parent 1218aff94d
commit 3bdaba2a93
5 changed files with 159 additions and 147 deletions

View File

@ -135,6 +135,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
"_RetVal", "_RetVal");
}
fprintf(client, "\n");
print_client( "RpcExceptionInit( 0, __client_finally );\n" );
if (has_full_pointer)
write_full_pointer_init(client, indent, func, FALSE);
@ -435,11 +436,18 @@ static void init_client(void)
fprintf(client, "\n");
print_client("#include \"%s\"\n", header_name);
print_client( "\n");
write_exceptions( client );
print_client( "\n");
print_client( "struct __client_frame\n");
print_client( "{\n");
print_client(" __DECL_EXCEPTION_FRAME;\n");
print_client( " MIDL_STUB_MESSAGE _StubMsg;\n");
print_client( "};\n");
print_client( "\n");
print_client("static void __client_finally( struct __client_frame *__frame )\n");
print_client( "{\n");
print_client( "}\n");
print_client( "\n");
}

View File

@ -109,105 +109,30 @@ static void init_proxy(const statement_list_t *stmts)
print_proxy( "\n");
print_proxy( "#include \"%s\"\n", header_name);
print_proxy( "\n");
print_proxy( "#ifndef USE_COMPILER_EXCEPTIONS\n");
print_proxy( "\n");
print_proxy( "#include \"wine/exception.h\"\n");
print_proxy( "#undef RpcTryExcept\n");
print_proxy( "#undef RpcExcept\n");
print_proxy( "#undef RpcEndExcept\n");
print_proxy( "#undef RpcTryFinally\n");
print_proxy( "#undef RpcFinally\n");
print_proxy( "#undef RpcEndFinally\n");
print_proxy( "#undef RpcExceptionCode\n");
print_proxy( "\n");
print_proxy( "struct __proxy_frame\n");
print_proxy( "{\n");
print_proxy( " EXCEPTION_REGISTRATION_RECORD frame;\n");
print_proxy( " sigjmp_buf jmp;\n");
print_proxy( " DWORD code;\n");
print_proxy( " MIDL_STUB_MESSAGE _StubMsg;\n");
print_proxy( " void *this;\n");
print_proxy( " int fullptr;\n");
print_proxy( "};\n");
print_proxy( "\n");
print_proxy("static void __proxy_finally_handler( struct __proxy_frame *frame )\n");
print_proxy( "{\n");
print_proxy( " if (frame->fullptr) NdrFullPointerXlatFree( frame->_StubMsg.FullPtrXlatTables );\n");
print_proxy( " if (frame->this) NdrProxyFreeBuffer( frame->this, &frame->_StubMsg );\n" );
print_proxy( "}\n\n");
print_proxy( "static DWORD __proxy_exception_handler( EXCEPTION_RECORD *record,\n");
print_proxy( " EXCEPTION_REGISTRATION_RECORD *frame,\n");
print_proxy( " CONTEXT *context,\n");
print_proxy( " EXCEPTION_REGISTRATION_RECORD **pdispatcher )\n");
print_proxy( "{\n");
print_proxy( " struct __proxy_frame *proxy_frame = (struct __proxy_frame *)frame;\n");
print_proxy( "\n");
print_proxy( " if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND | EH_NESTED_CALL))\n");
print_proxy( " {\n" );
print_proxy( " if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))\n");
print_proxy( " __proxy_finally_handler( proxy_frame );\n");
print_proxy( " return ExceptionContinueSearch;\n");
print_proxy( " }\n" );
print_proxy( " if (proxy_frame->_StubMsg.dwStubPhase == PROXY_SENDRECEIVE)\n");
print_proxy( " return ExceptionContinueSearch;\n");
print_proxy( "\n");
print_proxy( " proxy_frame->code = record->ExceptionCode;\n");
print_proxy( " __wine_rtl_unwind( frame, record );\n");
print_proxy( " __proxy_finally_handler( proxy_frame );\n");
print_proxy( " __wine_pop_frame( frame );\n");
print_proxy( " siglongjmp( proxy_frame->jmp, 1 );\n");
print_proxy( "}\n");
print_proxy( "\n");
print_proxy( "#define RpcTryExcept \\\n");
print_proxy( " __frame->frame.Handler = __proxy_exception_handler; \\\n");
print_proxy( " if (!sigsetjmp( __frame->jmp, 0 )) \\\n");
print_proxy( " { \\\n");
print_proxy( " __wine_push_frame( &__frame->frame ); \\\n");
print_proxy( " {\n");
print_proxy( "\n");
print_proxy( "#define RpcExcept(expr) \\\n");
print_proxy( " } \\\n");
print_proxy( " __wine_pop_frame( &__frame->frame ); \\\n");
print_proxy( " } \\\n");
print_proxy( " else\n");
print_proxy( "\n");
print_proxy( "#define RpcEndExcept\n");
print_proxy( "\n");
print_proxy( "#define RpcExceptionCode() (__frame->code)\n");
print_proxy( "\n");
print_proxy( "#define RpcTryFinallyProxy(ptr) \\\n");
print_proxy(" __frame->this = This; \\\n");
print_proxy(" __frame->fullptr = ptr;\n");
print_proxy( "\n");
print_proxy( "#define RpcFinallyProxy \\\n");
print_proxy(" __frame->this = 0; \\\n");
print_proxy(" __frame->fullptr = 0;\n");
print_proxy( "\n");
print_proxy( "#define RpcTryFinallyStub\n");
print_proxy( "\n");
print_proxy( "#define RpcFinallyStub\n");
print_proxy( "\n");
print_proxy( "#define RpcEndFinally\n");
print_proxy( "\n");
print_proxy( "#else /* USE_COMPILER_EXCEPTIONS */\n");
print_proxy( "\n");
print_proxy( "#define RpcTryFinallyProxy(ptr) RpcTryFinally\n");
print_proxy( "#define RpcTryFinallyStub RpcTryFinally\n");
print_proxy( "#define RpcFinallyProxy RpcFinally\n");
print_proxy( "#define RpcFinallyStub RpcFinally\n");
write_exceptions( proxy );
print_proxy( "\n");
print_proxy( "struct __proxy_frame\n");
print_proxy( "{\n");
print_proxy( " __DECL_EXCEPTION_FRAME;\n");
print_proxy( " MIDL_STUB_MESSAGE _StubMsg;\n");
print_proxy( " void *This;\n");
print_proxy( "};\n");
print_proxy( "\n");
print_proxy( "#endif /* USE_COMPILER_EXCEPTIONS */\n");
print_proxy( "\n");
print_proxy( "struct __stub_frame\n");
print_proxy( "{\n");
print_proxy( " __DECL_EXCEPTION_FRAME;\n");
print_proxy( " MIDL_STUB_MESSAGE _StubMsg;\n");
print_proxy( "};\n");
print_proxy( "\n");
print_proxy("static int __proxy_filter( struct __proxy_frame *__frame )\n");
print_proxy( "{\n");
print_proxy( " return (__frame->_StubMsg.dwStubPhase != PROXY_SENDRECEIVE);\n");
print_proxy( "}\n");
print_proxy( "\n");
print_proxy("static void __stub_finally( struct __stub_frame *__frame )\n");
print_proxy( "{\n");
print_proxy( "}\n");
print_proxy( "\n");
write_formatstringsdecl(proxy, indent, stmts, need_proxy);
write_stubdescproto();
}
@ -362,6 +287,16 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
if (!callconv) callconv = "";
indent = 0;
print_proxy( "static void __finally_%s_%s_Proxy( struct __proxy_frame *__frame )\n",
iface->name, get_name(def) );
print_proxy( "{\n");
indent++;
if (has_full_pointer) write_full_pointer_free(proxy, indent, cur);
print_proxy( "NdrProxyFreeBuffer( __frame->This, &__frame->_StubMsg );\n" );
indent--;
print_proxy( "}\n");
print_proxy( "\n");
write_type_decl_left(proxy, get_func_return_type(cur));
print_proxy( " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(def));
write_args(proxy, cur->args, iface->name, 1, TRUE);
@ -383,6 +318,9 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
}
print_proxy( "\n");
print_proxy( "RpcExceptionInit( __proxy_filter, __finally_%s_%s_Proxy );\n", iface->name, get_name(def) );
print_proxy( "__frame->This = This;\n" );
if (has_full_pointer)
write_full_pointer_init(proxy, indent, cur, FALSE);
@ -395,7 +333,7 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
print_proxy( "NdrProxyInitialize(This, &_RpcMessage, &__frame->_StubMsg, &Object_StubDesc, %d);\n", idx);
proxy_check_pointers( cur->args );
print_proxy( "RpcTryFinallyProxy(%d)\n", has_full_pointer );
print_proxy( "RpcTryFinally\n" );
print_proxy( "{\n" );
indent++;
@ -429,12 +367,10 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
indent--;
print_proxy( "}\n");
print_proxy( "RpcFinallyProxy\n" );
print_proxy( "RpcFinally\n" );
print_proxy( "{\n" );
indent++;
if (has_full_pointer)
write_full_pointer_free(proxy, indent, cur);
print_proxy( "NdrProxyFreeBuffer(This, &__frame->_StubMsg);\n" );
print_proxy( "__finally_%s_%s_Proxy( __frame );\n", iface->name, get_name(def) );
indent--;
print_proxy( "}\n");
print_proxy( "RpcEndFinally\n" );
@ -486,10 +422,11 @@ static void gen_stub(type_t *iface, const func_t *cur, const char *cas,
print_proxy("NdrStubInitialize(_pRpcMessage, &__frame->_StubMsg, &Object_StubDesc, _pRpcChannelBuffer);\n");
fprintf(proxy, "\n");
print_proxy( "RpcExceptionInit( 0, __stub_finally );\n" );
write_parameters_init(proxy, indent, cur);
print_proxy("RpcTryFinallyStub\n");
print_proxy("RpcTryFinally\n");
print_proxy("{\n");
indent++;
if (has_full_pointer)
@ -539,7 +476,7 @@ static void gen_stub(type_t *iface, const func_t *cur, const char *cas,
indent--;
print_proxy("}\n");
print_proxy("RpcFinallyStub\n");
print_proxy("RpcFinally\n");
print_proxy("{\n");
write_remoting_arguments(proxy, indent+1, cur, PASS_OUT, PHASE_FREE);

View File

@ -85,6 +85,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
print_server("&%s_StubDesc);\n", iface->name);
indent--;
fprintf(server, "\n");
print_server( "RpcExceptionInit( __server_filter, __server_finally );\n" );
write_parameters_init(server, indent, func);
@ -370,63 +371,23 @@ static void init_server(void)
fprintf(server, "\n");
print_server("#include \"%s\"\n", header_name);
print_server("\n");
print_server("#ifndef USE_COMPILER_EXCEPTIONS\n");
write_exceptions( server );
print_server("\n");
print_server("#include \"wine/exception.h\"\n");
print_server("#undef RpcTryExcept\n");
print_server("#undef RpcExcept\n");
print_server("#undef RpcEndExcept\n");
print_server("#undef RpcExceptionCode\n");
print_server("\n");
print_server( "struct __server_frame\n");
print_server( "{\n");
print_server( " EXCEPTION_REGISTRATION_RECORD frame;\n");
print_server( " sigjmp_buf jmp;\n");
print_server( " MIDL_STUB_MESSAGE _StubMsg;\n");
print_server( "};\n");
print_server( "\n");
print_server("static DWORD __server_exception_handler( EXCEPTION_RECORD *record,\n");
print_server(" EXCEPTION_REGISTRATION_RECORD *frame,\n");
print_server(" CONTEXT *context,\n");
print_server(" EXCEPTION_REGISTRATION_RECORD **pdispatcher )\n");
print_server("struct __server_frame\n");
print_server("{\n");
print_server(" struct __server_frame *server_frame = (struct __server_frame *)frame;\n");
print_server(" __DECL_EXCEPTION_FRAME;\n");
print_server(" MIDL_STUB_MESSAGE _StubMsg;\n");
print_server("};\n");
print_server("\n");
print_server(" if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND | EH_NESTED_CALL))\n");
print_server(" return ExceptionContinueSearch;\n");
print_server("\n");
print_server(" if (record->ExceptionCode != STATUS_ACCESS_VIOLATION &&\n");
print_server(" record->ExceptionCode != STATUS_DATATYPE_MISALIGNMENT &&\n");
print_server(" record->ExceptionCode != RPC_X_BAD_STUB_DATA &&\n");
print_server(" record->ExceptionCode != RPC_S_INVALID_BOUND)\n");
print_server(" return ExceptionContinueSearch;\n");
print_server("\n");
print_server(" __wine_rtl_unwind( frame, record );\n");
print_server(" __wine_pop_frame( frame );\n");
print_server(" siglongjmp( server_frame->jmp, 1 );\n");
print_server("}\n");
print_server("#define RpcTryExcept \\\n");
print_server(" __frame->frame.Handler = __server_exception_handler; \\\n");
print_server(" if (!sigsetjmp( __frame->jmp, 0 )) \\\n");
print_server(" { \\\n");
print_server(" __wine_push_frame( &__frame->frame );\n");
print_server("\n");
print_server("#define RpcExcept(expr) \\\n");
print_server(" __wine_pop_frame( &__frame->frame ); \\\n");
print_server(" } \\\n");
print_server(" else\n");
print_server("\n");
print_server("#define RpcEndExcept\n");
print_server("\n");
print_server( "#else /* USE_COMPILER_EXCEPTIONS */\n");
print_server( "\n");
print_server( "struct __server_frame\n");
print_server("static int __server_filter( struct __server_frame *__frame )\n");
print_server( "{\n");
print_server( " MIDL_STUB_MESSAGE _StubMsg;\n");
print_server( "};\n");
print_server( " return RPC_BAD_STUB_DATA_EXCEPTION_FILTER;\n");
print_server( "}\n");
print_server( "\n");
print_server("static void __server_finally( struct __server_frame *__frame )\n");
print_server( "{\n");
print_server( "}\n");
print_server( "\n");
print_server("#endif /* USE_COMPILER_EXCEPTIONS */\n");
print_server("\n");
}

View File

@ -3372,3 +3372,108 @@ void write_endpoints( FILE *f, const char *prefix, const str_list_t *list )
error:
error("Invalid endpoint syntax '%s'\n", endpoint->str);
}
void write_exceptions( FILE *file )
{
fprintf( file, "#ifndef USE_COMPILER_EXCEPTIONS\n");
fprintf( file, "\n");
fprintf( file, "#include \"wine/exception.h\"\n");
fprintf( file, "#undef RpcTryExcept\n");
fprintf( file, "#undef RpcExcept\n");
fprintf( file, "#undef RpcEndExcept\n");
fprintf( file, "#undef RpcTryFinally\n");
fprintf( file, "#undef RpcFinally\n");
fprintf( file, "#undef RpcEndFinally\n");
fprintf( file, "#undef RpcExceptionCode\n");
fprintf( file, "\n");
fprintf( file, "struct __exception_frame;\n");
fprintf( file, "typedef int (*__filter_func)(EXCEPTION_RECORD *, struct __exception_frame *);\n");
fprintf( file, "typedef void (*__finally_func)(struct __exception_frame *);\n");
fprintf( file, "\n");
fprintf( file, "#define __DECL_EXCEPTION_FRAME \\\n");
fprintf( file, " EXCEPTION_REGISTRATION_RECORD frame; \\\n");
fprintf( file, " __filter_func filter; \\\n");
fprintf( file, " __finally_func finally; \\\n");
fprintf( file, " sigjmp_buf jmp; \\\n");
fprintf( file, " DWORD code; \\\n");
fprintf( file, " unsigned char filter_level; \\\n");
fprintf( file, " unsigned char finally_level;\n");
fprintf( file, "\n");
fprintf( file, "struct __exception_frame\n{\n");
fprintf( file, " __DECL_EXCEPTION_FRAME;\n");
fprintf( file, "};\n");
fprintf( file, "\n");
fprintf( file, "static DWORD __widl_exception_handler( EXCEPTION_RECORD *record,\n");
fprintf( file, " EXCEPTION_REGISTRATION_RECORD *frame,\n");
fprintf( file, " CONTEXT *context,\n");
fprintf( file, " EXCEPTION_REGISTRATION_RECORD **pdispatcher )\n");
fprintf( file, "{\n");
fprintf( file, " struct __exception_frame *exc_frame = (struct __exception_frame *)frame;\n");
fprintf( file, "\n");
fprintf( file, " if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND | EH_NESTED_CALL))\n");
fprintf( file, " {\n" );
fprintf( file, " if (exc_frame->finally_level && (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)))\n");
fprintf( file, " exc_frame->finally( exc_frame );\n");
fprintf( file, " return ExceptionContinueSearch;\n");
fprintf( file, " }\n" );
fprintf( file, " exc_frame->code = record->ExceptionCode;\n");
fprintf( file, " if (exc_frame->filter_level && exc_frame->filter( record, exc_frame ) == EXCEPTION_EXECUTE_HANDLER)\n" );
fprintf( file, " {\n");
fprintf( file, " __wine_rtl_unwind( frame, record );\n");
fprintf( file, " if (exc_frame->finally_level > exc_frame->filter_level)\n" );
fprintf( file, " {\n");
fprintf( file, " exc_frame->finally( exc_frame );\n");
fprintf( file, " __wine_pop_frame( frame );\n");
fprintf( file, " }\n");
fprintf( file, " exc_frame->filter_level = 0;\n");
fprintf( file, " siglongjmp( exc_frame->jmp, 1 );\n");
fprintf( file, " }\n");
fprintf( file, " return ExceptionContinueSearch;\n");
fprintf( file, "}\n");
fprintf( file, "\n");
fprintf( file, "#define RpcTryExcept \\\n");
fprintf( file, " if (!sigsetjmp( __frame->jmp, 0 )) \\\n");
fprintf( file, " { \\\n");
fprintf( file, " if (!__frame->finally_level) \\\n" );
fprintf( file, " __wine_push_frame( &__frame->frame ); \\\n");
fprintf( file, " __frame->filter_level = __frame->finally_level + 1;\n" );
fprintf( file, "\n");
fprintf( file, "#define RpcExcept(expr) \\\n");
fprintf( file, " if (!__frame->finally_level) \\\n" );
fprintf( file, " __wine_pop_frame( &__frame->frame ); \\\n");
fprintf( file, " __frame->filter_level = 0; \\\n" );
fprintf( file, " } \\\n");
fprintf( file, " else \\\n");
fprintf( file, "\n");
fprintf( file, "#define RpcEndExcept\n");
fprintf( file, "\n");
fprintf( file, "#define RpcExceptionCode() (__frame->code)\n");
fprintf( file, "\n");
fprintf( file, "#define RpcTryFinally \\\n");
fprintf( file, " if (!__frame->filter_level) \\\n");
fprintf( file, " __wine_push_frame( &__frame->frame ); \\\n");
fprintf( file, " __frame->finally_level = __frame->filter_level + 1;\n");
fprintf( file, "\n");
fprintf( file, "#define RpcFinally \\\n");
fprintf( file, " if (!__frame->filter_level) \\\n");
fprintf( file, " __wine_pop_frame( &__frame->frame ); \\\n");
fprintf( file, " __frame->finally_level = 0;\n");
fprintf( file, "\n");
fprintf( file, "#define RpcEndFinally\n");
fprintf( file, "\n");
fprintf( file, "#define RpcExceptionInit(filter_func,finally_func) \\\n");
fprintf( file, " do { \\\n");
fprintf( file, " __frame->frame.Handler = __widl_exception_handler; \\\n");
fprintf( file, " __frame->filter = (__filter_func)(filter_func); \\\n" );
fprintf( file, " __frame->finally = (__finally_func)(finally_func); \\\n");
fprintf( file, " __frame->filter_level = 0; \\\n");
fprintf( file, " __frame->finally_level = 0; \\\n");
fprintf( file, " } while (0)\n");
fprintf( file, "\n");
fprintf( file, "#else /* USE_COMPILER_EXCEPTIONS */\n");
fprintf( file, "\n");
fprintf( file, "#define RpcExceptionInit(filter_func,finally_func) do {} while(0)\n");
fprintf( file, "#define __DECL_EXCEPTION_FRAME\n");
fprintf( file, "\n");
fprintf( file, "#endif /* USE_COMPILER_EXCEPTIONS */\n");
}

View File

@ -53,6 +53,7 @@ int write_expr_eval_routines(FILE *file, const char *iface);
void write_expr_eval_routine_list(FILE *file, const char *iface);
void write_user_quad_list(FILE *file);
void write_endpoints( FILE *f, const char *prefix, const str_list_t *list );
void write_exceptions( FILE *file );
size_t type_memsize(const type_t *t, unsigned int *align);
int decl_indirect(const type_t *t);
void write_parameters_init(FILE *file, int indent, const func_t *func);