Rob Shearman : widl: Output code for initialising and freeing full pointer translation tables.

Alexandre Julliard julliard at winehq.org
Mon Feb 4 08:42:55 CST 2008


Module: wine
Branch: master
Commit: 661b01f92248206df7a86c8aa94caf102ccc4c95
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=661b01f92248206df7a86c8aa94caf102ccc4c95

Author: Rob Shearman <rob at codeweavers.com>
Date:   Wed Jan 30 22:29:39 2008 +0000

widl: Output code for initialising and freeing full pointer translation tables.

---

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

diff --git a/tools/widl/client.c b/tools/widl/client.c
index 5cd2a81..2eaa43c 100644
--- a/tools/widl/client.c
+++ b/tools/widl/client.c
@@ -85,6 +85,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
     {
         const var_t *def = func->def;
         const var_t* explicit_handle_var;
+        int has_full_pointer = is_full_pointer_function(func);
 
         /* check for a defined binding handle */
         explicit_handle_var = get_explicit_handle_var(func);
@@ -142,6 +143,9 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
         }
         fprintf(client, "\n");
 
+        if (has_full_pointer)
+            write_full_pointer_init(client, indent, func, FALSE);
+
         /* check pointers */
         check_pointers(func);
 
@@ -245,6 +249,9 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
 
         /* FIXME: emit client finally code */
 
+        if (has_full_pointer)
+            write_full_pointer_free(client, indent, func);
+
         print_client("NdrFreeBuffer((PMIDL_STUB_MESSAGE)&_StubMsg);\n");
 
         indent--;
diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c
index 731629f..217c64b 100644
--- a/tools/widl/proxy.c
+++ b/tools/widl/proxy.c
@@ -254,6 +254,7 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
 {
   var_t *def = cur->def;
   int has_ret = !is_void(def->type);
+  int has_full_pointer = is_full_pointer_function(cur);
 
   indent = 0;
   write_type_decl_left(proxy, def->type);
@@ -279,6 +280,9 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
   }
   print_proxy( "\n");
 
+  if (has_full_pointer)
+    write_full_pointer_init(proxy, indent, cur, FALSE);
+
   /* FIXME: trace */
   clear_output_vars( cur->args );
 
@@ -325,6 +329,8 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
   print_proxy( "RpcFinally\n" );
   print_proxy( "{\n" );
   indent++;
+  if (has_full_pointer)
+    write_full_pointer_free(proxy, indent, cur);
   print_proxy( "NdrProxyFreeBuffer(This, &_StubMsg);\n" );
   indent--;
   print_proxy( "}\n");
@@ -356,6 +362,7 @@ static void gen_stub(type_t *iface, const func_t *cur, const char *cas,
   var_t *def = cur->def;
   const var_t *arg;
   int has_ret = !is_void(def->type);
+  int has_full_pointer = is_full_pointer_function(cur);
 
   indent = 0;
   print_proxy( "void __RPC_STUB %s_", iface->name);
@@ -384,6 +391,8 @@ static void gen_stub(type_t *iface, const func_t *cur, const char *cas,
   print_proxy("RpcTryFinally\n");
   print_proxy("{\n");
   indent++;
+  if (has_full_pointer)
+    write_full_pointer_init(proxy, indent, cur, TRUE);
   print_proxy("if ((_pRpcMessage->DataRepresentation & 0xffff) != NDR_LOCAL_DATA_REPRESENTATION)\n");
   indent++;
   print_proxy("NdrConvert( &_StubMsg, &__MIDL_ProcFormatString.Format[%u]);\n", proc_offset );
@@ -439,6 +448,9 @@ static void gen_stub(type_t *iface, const func_t *cur, const char *cas,
 
   write_remoting_arguments(proxy, indent+1, cur, PASS_OUT, PHASE_FREE);
 
+  if (has_full_pointer)
+    write_full_pointer_free(proxy, indent, cur);
+
   print_proxy("}\n");
   print_proxy("RpcEndFinally\n");
 
diff --git a/tools/widl/server.c b/tools/widl/server.c
index 3bcd231..53dd099 100644
--- a/tools/widl/server.c
+++ b/tools/widl/server.c
@@ -62,6 +62,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
     LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry )
     {
         const var_t *def = func->def;
+        int has_full_pointer = is_full_pointer_function(func);
 
         /* check for a defined binding handle */
         explicit_handle_var = get_explicit_handle_var(func);
@@ -126,6 +127,9 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
         print_server("{\n");
         indent++;
 
+        if (has_full_pointer)
+            write_full_pointer_init(server, indent, func, TRUE);
+
         if (func->args)
         {
             print_server("if ((_pRpcMessage->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n");
@@ -236,6 +240,9 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
 
         write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_FREE);
 
+        if (has_full_pointer)
+            write_full_pointer_free(server, indent, func);
+
         indent--;
         print_server("}\n");
         print_server("RpcEndFinally\n");
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 0e8a096..41dd22f 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -193,6 +193,46 @@ static int type_has_pointers(const type_t *type)
     return FALSE;
 }
 
+static int type_has_full_pointer(const type_t *type)
+{
+    if (is_user_type(type))
+        return FALSE;
+    else if (type->type == RPC_FC_FP)
+        return TRUE;
+    else if (is_ptr(type))
+        return FALSE;
+    else if (is_array(type))
+        return type_has_full_pointer(type->ref);
+    else if (is_struct(type->type))
+    {
+        const var_t *field;
+        if (type->fields) LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry )
+        {
+            if (type_has_full_pointer(field->type))
+                return TRUE;
+        }
+    }
+    else if (is_union(type->type))
+    {
+        var_list_t *fields;
+        const var_t *field;
+        if (type->type == RPC_FC_ENCAPSULATED_UNION)
+        {
+            const var_t *uv = LIST_ENTRY(list_tail(type->fields), const var_t, entry);
+            fields = uv->type->fields;
+        }
+        else
+            fields = type->fields;
+        if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
+        {
+            if (field->type && type_has_full_pointer(field->type))
+                return TRUE;
+        }
+    }
+
+    return FALSE;
+}
+
 static unsigned short user_type_offset(const char *name)
 {
     user_type_t *ut;
@@ -903,6 +943,32 @@ size_t type_memsize(const type_t *t, unsigned int *align)
     return size;
 }
 
+int is_full_pointer_function(const func_t *func)
+{
+    const var_t *var;
+    if (type_has_full_pointer(func->def->type))
+        return TRUE;
+    if (!func->args)
+        return FALSE;
+    LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
+        if (type_has_full_pointer( var->type ))
+            return TRUE;
+    return FALSE;
+}
+
+void write_full_pointer_init(FILE *file, int indent, const func_t *func, int is_server)
+{
+    print_file(file, indent, "_StubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,%s);\n",
+                   is_server ? "XLAT_SERVER" : "XLAT_CLIENT");
+    fprintf(file, "\n");
+}
+
+void write_full_pointer_free(FILE *file, int indent, const func_t *func)
+{
+    print_file(file, indent, "NdrFullPointerXlatFree(_StubMsg.FullPtrXlatTables);\n");
+    fprintf(file, "\n");
+}
+
 static unsigned int write_nonsimple_pointer(FILE *file, const type_t *type, size_t offset)
 {
     short absoff = type->ref->typestring_offset;
diff --git a/tools/widl/typegen.h b/tools/widl/typegen.h
index c9a5148..4408ffa 100644
--- a/tools/widl/typegen.h
+++ b/tools/widl/typegen.h
@@ -60,3 +60,6 @@ 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);
+int is_full_pointer_function(const func_t *func);
+void write_full_pointer_init(FILE *file, int indent, const func_t *func, int is_server);
+void write_full_pointer_free(FILE *file, int indent, const func_t *func);




More information about the wine-cvs mailing list