Alexandre Julliard : widl: Pass a structure containing the parameters to NdrClientCall instead of accessing the stack .

Alexandre Julliard julliard at winehq.org
Thu Jun 9 11:47:38 CDT 2011


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Jun  9 11:42:21 2011 +0200

widl: Pass a structure containing the parameters to NdrClientCall instead of accessing the stack.

---

 tools/widl/proxy.c   |    3 ++-
 tools/widl/typegen.c |   41 ++++++++++++++++++++++++++++++++---------
 tools/widl/typegen.h |    3 ++-
 3 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c
index 0043e6a..7bc7753 100644
--- a/tools/widl/proxy.c
+++ b/tools/widl/proxy.c
@@ -502,7 +502,8 @@ static void gen_stub_thunk( type_t *iface, const var_t *func, unsigned int proc_
                  iface->name, get_name(func) );
     print_proxy( "{\n");
     indent++;
-    write_func_param_struct( proxy, iface, func->type, "pParamStruct" );
+    write_func_param_struct( proxy, iface, func->type,
+                             "*pParamStruct = (struct _PARAM_STRUCT *)pStubMsg->StackTop", has_ret );
     print_proxy( "%s%s_%s_Stub( pParamStruct->This",
                  has_ret ? "pParamStruct->_RetVal = " : "", iface->name, callas->name );
     indent++;
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index abe84d9..04e014a 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -4661,8 +4661,10 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
 }
 
 
-void write_func_param_struct( FILE *file, const type_t *iface, const type_t *func, const char *var_name )
+void write_func_param_struct( FILE *file, const type_t *iface, const type_t *func,
+                              const char *var_decl, int add_retval )
 {
+    type_t *rettype = type_function_get_rettype( func );
     const var_list_t *args = type_get_function_args( func );
     const var_t *arg;
 
@@ -4682,13 +4684,16 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun
         else
             fprintf( file, "%s DECLSPEC_ALIGN(%u);\n", arg->name, pointer_size );
     }
-    if (!is_void( type_function_get_rettype( func )))
+    if (add_retval && !is_void( rettype ))
     {
         print_file(file, 2, "%s", "");
-        write_type_decl( file, type_function_get_rettype( func ), "_RetVal" );
-        fprintf( file, ";\n" );
+        write_type_decl( file, rettype, "_RetVal" );
+        if (is_array( rettype ) || is_ptr( rettype ) || type_memsize( rettype ) == pointer_size)
+            fprintf( file, ";\n" );
+        else
+            fprintf( file, " DECLSPEC_ALIGN(%u);\n", pointer_size );
     }
-    print_file(file, 1, "} *%s = (struct _PARAM_STRUCT *)pStubMsg->StackTop;\n\n", var_name );
+    print_file(file, 1, "} %s;\n\n", var_decl );
 }
 
 int write_expr_eval_routines(FILE *file, const char *iface)
@@ -4709,7 +4714,8 @@ int write_expr_eval_routines(FILE *file, const char *iface)
         print_file(file, 0, "{\n");
         if (type_get_type( eval->cont_type ) == TYPE_FUNCTION)
         {
-            write_func_param_struct( file, eval->iface, eval->cont_type, "pS" );
+            write_func_param_struct( file, eval->iface, eval->cont_type,
+                                     "*pS = (struct _PARAM_STRUCT *)pStubMsg->StackTop", FALSE );
         }
         else
         {
@@ -4813,16 +4819,33 @@ void write_client_call_routine( FILE *file, const type_t *iface, const var_t *fu
     int has_ret = !is_void( rettype );
     const var_list_t *args = type_get_function_args( func->type );
     const var_t *arg;
-    int len;
+    int len, needs_params = 0;
+
+    /* we need a param structure if we have more than one arg */
+    if (pointer_size == 4 && args) needs_params = is_object( iface ) || list_count( args ) > 1;
 
     print_file( file, 0, "{\n");
-    if (has_ret) print_file( file, 1, "%s", "CLIENT_CALL_RETURN _RetVal;\n\n" );
+    if (needs_params)
+    {
+        if (has_ret) print_file( file, 1, "%s", "CLIENT_CALL_RETURN _RetVal;\n" );
+        write_func_param_struct( file, iface, func->type, "__params", FALSE );
+        if (is_object( iface )) print_file( file, 1, "__params.This = This;\n" );
+        if (args)
+            LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
+                print_file( file, 1, "__params.%s = %s;\n", arg->name, arg->name );
+    }
+    else if (has_ret) print_file( file, 1, "%s", "CLIENT_CALL_RETURN _RetVal;\n\n" );
+
     len = fprintf( file, "    %s%s( ",
                    has_ret ? "_RetVal = " : "",
                    get_stub_mode() == MODE_Oif ? "NdrClientCall2" : "NdrClientCall" );
     fprintf( file, "&%s_StubDesc,", prefix );
     fprintf( file, "\n%*s&__MIDL_ProcFormatString.Format[%u]", len, "", proc_offset );
-    if (pointer_size == 8)
+    if (needs_params)
+    {
+        fprintf( file, ",\n%*s&__params", len, "" );
+    }
+    else if (pointer_size == 8)
     {
         if (is_object( iface )) fprintf( file, ",\n%*sThis", len, "" );
         if (args)
diff --git a/tools/widl/typegen.h b/tools/widl/typegen.h
index 6c7242e..3efd421 100644
--- a/tools/widl/typegen.h
+++ b/tools/widl/typegen.h
@@ -75,7 +75,8 @@ unsigned int get_size_procformatstring(const statement_list_t *stmts, type_pred_
 unsigned int get_size_typeformatstring(const statement_list_t *stmts, type_pred_t pred);
 void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char *local_var_prefix );
 void declare_stub_args( FILE *file, int indent, const var_t *func );
-void write_func_param_struct( FILE *file, const type_t *iface, const type_t *func, const char *var_name );
+void write_func_param_struct( FILE *file, const type_t *iface, const type_t *func,
+                              const char *var_decl, int add_retval );
 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);




More information about the wine-cvs mailing list