Alexandre Julliard : widl: Sort the proxy interfaces by iid and use a binary search in IID_Lookup.

Alexandre Julliard julliard at winehq.org
Tue Dec 2 11:01:51 CST 2008


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Dec  1 16:25:45 2008 +0100

widl: Sort the proxy interfaces by iid and use a binary search in IID_Lookup.

---

 tools/widl/proxy.c |   95 ++++++++++++++++++++++++---------------------------
 1 files changed, 45 insertions(+), 50 deletions(-)

diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c
index 860b383..a994fd7 100644
--- a/tools/widl/proxy.c
+++ b/tools/widl/proxy.c
@@ -703,23 +703,16 @@ static void write_proxy_stmts(const statement_list_t *stmts, unsigned int *proc_
   }
 }
 
-static void write_proxy_iface_name_format(const statement_list_t *stmts, const char *format)
+static int cmp_iid( const void *ptr1, const void *ptr2 )
 {
-  const statement_t *stmt;
-  if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
-  {
-    if (stmt->type == STMT_LIBRARY)
-      write_proxy_iface_name_format(stmt->u.lib->stmts, format);
-    else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
-    {
-      type_t *iface = stmt->u.type;
-      if (iface->ref && need_proxy(iface))
-        fprintf(proxy, format, iface->name);
-    }
-  }
+    const type_t * const *iface1 = ptr1;
+    const type_t * const *iface2 = ptr2;
+    const UUID *uuid1 = get_attrp( (*iface1)->attrs, ATTR_UUID );
+    const UUID *uuid2 = get_attrp( (*iface2)->attrs, ATTR_UUID );
+    return memcmp( uuid1, uuid2, sizeof(UUID) );
 }
 
-static void write_proxy_iface_base_iids(const statement_list_t *stmts)
+static void build_iface_list( const statement_list_t *stmts, type_t **ifaces[], int *count )
 {
     const statement_t *stmt;
 
@@ -727,50 +720,36 @@ static void write_proxy_iface_base_iids(const statement_list_t *stmts)
     LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
     {
         if (stmt->type == STMT_LIBRARY)
-            write_proxy_iface_base_iids(stmt->u.lib->stmts);
+            build_iface_list(stmt->u.lib->stmts, ifaces, count);
         else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
         {
             type_t *iface = stmt->u.type;
             if (iface->ref && need_proxy(iface))
             {
-                if (need_delegation(iface))
-                    fprintf( proxy, "    &IID_%s,  /* %s */\n", iface->ref->name, iface->name );
-                else
-                    fprintf( proxy, "    0,\n" );
+                *ifaces = xrealloc( *ifaces, (*count + 1) * sizeof(*ifaces) );
+                (*ifaces)[(*count)++] = iface;
             }
         }
     }
 }
 
-static void write_iid_lookup(const statement_list_t *stmts, const char *file_id, int *c)
+static type_t **sort_interfaces( const statement_list_t *stmts, int *count )
 {
-  const statement_t *stmt;
-  if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
-  {
-    if (stmt->type == STMT_LIBRARY)
-      write_iid_lookup(stmt->u.lib->stmts, file_id, c);
-    else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
-    {
-      type_t *iface = stmt->u.type;
-      if(iface->ref && need_proxy(iface))
-      {
-        fprintf(proxy, "    if (!_%s_CHECK_IID(%d))\n", file_id, *c);
-        fprintf(proxy, "    {\n");
-        fprintf(proxy, "        *pIndex = %d;\n", *c);
-        fprintf(proxy, "        return 1;\n");
-        fprintf(proxy, "    }\n");
-        (*c)++;
-      }
-    }
-  }
+    type_t **ifaces = NULL;
+
+    *count = 0;
+    build_iface_list( stmts, &ifaces, count );
+    qsort( ifaces, *count, sizeof(*ifaces), cmp_iid );
+    return ifaces;
 }
 
 void write_proxies(const statement_list_t *stmts)
 {
   int expr_eval_routines;
   char *file_id = proxy_token;
-  int c, have_baseiid;
+  int i, count, have_baseiid;
   unsigned int proc_offset = 0;
+  type_t **interfaces;
 
   if (!do_proxies) return;
   if (do_everything && !need_proxy_file(stmts)) return;
@@ -793,23 +772,27 @@ void write_proxies(const statement_list_t *stmts)
   write_procformatstring(proxy, stmts, need_proxy);
   write_typeformatstring(proxy, stmts, need_proxy);
 
+  interfaces = sort_interfaces(stmts, &count);
   fprintf(proxy, "static const CInterfaceProxyVtbl* const _%s_ProxyVtblList[] =\n", file_id);
   fprintf(proxy, "{\n");
-  write_proxy_iface_name_format(stmts, "    (const CInterfaceProxyVtbl*)&_%sProxyVtbl,\n");
+  for (i = 0; i < count; i++)
+      fprintf(proxy, "    (const CInterfaceProxyVtbl*)&_%sProxyVtbl,\n", interfaces[i]->name);
   fprintf(proxy, "    0\n");
   fprintf(proxy, "};\n");
   fprintf(proxy, "\n");
 
   fprintf(proxy, "static const CInterfaceStubVtbl* const _%s_StubVtblList[] =\n", file_id);
   fprintf(proxy, "{\n");
-  write_proxy_iface_name_format(stmts, "    &_%sStubVtbl,\n");
+  for (i = 0; i < count; i++)
+      fprintf(proxy, "    &_%sStubVtbl,\n", interfaces[i]->name);
   fprintf(proxy, "    0\n");
   fprintf(proxy, "};\n");
   fprintf(proxy, "\n");
 
   fprintf(proxy, "static PCInterfaceName const _%s_InterfaceNamesList[] =\n", file_id);
   fprintf(proxy, "{\n");
-  write_proxy_iface_name_format(stmts, "    \"%s\",\n");
+  for (i = 0; i < count; i++)
+      fprintf(proxy, "    \"%s\",\n", interfaces[i]->name);
   fprintf(proxy, "    0\n");
   fprintf(proxy, "};\n");
   fprintf(proxy, "\n");
@@ -818,18 +801,30 @@ void write_proxies(const statement_list_t *stmts)
   {
       fprintf(proxy, "static const IID * _%s_BaseIIDList[] =\n", file_id);
       fprintf(proxy, "{\n");
-      write_proxy_iface_base_iids(stmts);
+      for (i = 0; i < count; i++)
+      {
+          if (need_delegation(interfaces[i]))
+              fprintf( proxy, "    &IID_%s,  /* %s */\n", interfaces[i]->ref->name, interfaces[i]->name );
+          else
+              fprintf( proxy, "    0,\n" );
+      }
       fprintf(proxy, "    0\n");
       fprintf(proxy, "};\n");
       fprintf(proxy, "\n");
   }
 
-  fprintf(proxy, "#define _%s_CHECK_IID(n) IID_GENERIC_CHECK_IID(_%s, pIID, n)\n", file_id, file_id);
-  fprintf(proxy, "\n");
-  fprintf(proxy, "int __stdcall _%s_IID_Lookup(const IID* pIID, int* pIndex)\n", file_id);
+  fprintf(proxy, "static int __stdcall _%s_IID_Lookup(const IID* pIID, int* pIndex)\n", file_id);
   fprintf(proxy, "{\n");
-  c = 0;
-  write_iid_lookup(stmts, file_id, &c);
+  fprintf(proxy, "    int low = 0, high = %d;\n", count - 1);
+  fprintf(proxy, "\n");
+  fprintf(proxy, "    while (low <= high)\n");
+  fprintf(proxy, "    {\n");
+  fprintf(proxy, "        int pos = (low + high) / 2;\n");
+  fprintf(proxy, "        int res = IID_GENERIC_CHECK_IID(_%s, pIID, pos);\n", file_id);
+  fprintf(proxy, "        if (!res) { *pIndex = pos; return 1; }\n");
+  fprintf(proxy, "        if (res > 0) low = pos + 1;\n");
+  fprintf(proxy, "        else high = pos - 1;\n");
+  fprintf(proxy, "    }\n");
   fprintf(proxy, "    return 0;\n");
   fprintf(proxy, "}\n");
   fprintf(proxy, "\n");
@@ -842,7 +837,7 @@ void write_proxies(const statement_list_t *stmts)
   if (have_baseiid) fprintf(proxy, "    _%s_BaseIIDList,\n", file_id);
   else fprintf(proxy, "    0,\n");
   fprintf(proxy, "    &_%s_IID_Lookup,\n", file_id);
-  fprintf(proxy, "    %d,\n", c);
+  fprintf(proxy, "    %d,\n", count);
   fprintf(proxy, "    1,\n");
   fprintf(proxy, "    0,\n");
   fprintf(proxy, "    0,\n");




More information about the wine-cvs mailing list