Alexandre Julliard : winebuild: Make thiscall an entry point flag instead of a function type.

Alexandre Julliard julliard at winehq.org
Thu Feb 28 16:09:42 CST 2019


Module: wine
Branch: master
Commit: 28debd82fc90e551e8fa8fbee8858df237cb3301
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=28debd82fc90e551e8fa8fbee8858df237cb3301

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Feb 27 17:09:51 2019 +0100

winebuild: Make thiscall an entry point flag instead of a function type.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 tools/winebuild/build.h          |  2 +-
 tools/winebuild/import.c         |  2 --
 tools/winebuild/parser.c         | 40 +++++++++++++++++++++++++++-------------
 tools/winebuild/spec32.c         | 12 +++++-------
 tools/winebuild/winebuild.man.in | 11 ++++++-----
 5 files changed, 39 insertions(+), 28 deletions(-)

diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h
index fbc2cd9..15d22a0 100644
--- a/tools/winebuild/build.h
+++ b/tools/winebuild/build.h
@@ -47,7 +47,6 @@ typedef enum
     TYPE_STDCALL,      /* stdcall function (Win32) */
     TYPE_CDECL,        /* cdecl function (Win32) */
     TYPE_VARARGS,      /* varargs function (Win32) */
-    TYPE_THISCALL,     /* thiscall function (Win32 on i386) */
     TYPE_EXTERN,       /* external symbol (Win32) */
     TYPE_NBTYPES
 } ORD_TYPE;
@@ -173,6 +172,7 @@ struct strarray
 #define FLAG_REGISTER  0x10  /* use register calling convention */
 #define FLAG_PRIVATE   0x20  /* function is private (cannot be imported) */
 #define FLAG_ORDINAL   0x40  /* function should be imported by ordinal */
+#define FLAG_THISCALL  0x80  /* use thiscall calling convention */
 
 #define FLAG_FORWARD   0x100  /* function is a forwarded name */
 #define FLAG_EXT_LINK  0x200  /* function links to an external symbol */
diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c
index 5e5866c..893691e 100644
--- a/tools/winebuild/import.c
+++ b/tools/winebuild/import.c
@@ -466,7 +466,6 @@ static void check_undefined_exports( DLLSPEC *spec )
             case TYPE_STDCALL:
             case TYPE_CDECL:
             case TYPE_VARARGS:
-            case TYPE_THISCALL:
                 if (link_ext_symbols)
                 {
                     odp->flags |= FLAG_EXT_LINK;
@@ -1444,7 +1443,6 @@ static void build_unix_import_lib( DLLSPEC *spec )
         case TYPE_VARARGS:
         case TYPE_CDECL:
         case TYPE_STDCALL:
-        case TYPE_THISCALL:
             prefix = (!odp->name || (odp->flags & FLAG_ORDINAL)) ? import_ord_prefix : import_func_prefix;
             new_output_as_file( spec->file_name );
             output( "\t.text\n" );
diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c
index ad99654..11b05aa 100644
--- a/tools/winebuild/parser.c
+++ b/tools/winebuild/parser.c
@@ -56,7 +56,6 @@ static const char * const TypeNames[TYPE_NBTYPES] =
     "stdcall",      /* TYPE_STDCALL */
     "cdecl",        /* TYPE_CDECL */
     "varargs",      /* TYPE_VARARGS */
-    "thiscall",     /* TYPE_THISCALL */
     "extern"        /* TYPE_EXTERN */
 };
 
@@ -69,6 +68,7 @@ static const char * const FlagNames[] =
     "register",    /* FLAG_REGISTER */
     "private",     /* FLAG_PRIVATE */
     "ordinal",     /* FLAG_ORDINAL */
+    "thiscall",    /* FLAG_THISCALL */
     NULL
 };
 
@@ -287,10 +287,18 @@ static int parse_spec_arguments( ORDDEF *odp, DLLSPEC *spec, int optional )
     }
 
     odp->u.func.nb_args = i;
-    if (odp->type == TYPE_THISCALL && (!i || odp->u.func.args[0] != ARG_PTR))
+    if (odp->flags & FLAG_THISCALL)
     {
-        error( "First argument of a thiscall function must be a pointer\n" );
-        return 0;
+        if (odp->type != TYPE_STDCALL)
+        {
+            error( "A thiscall function must use the stdcall convention\n" );
+            return 0;
+        }
+        if (!i || odp->u.func.args[0] != ARG_PTR)
+        {
+            error( "First argument of a thiscall function must be a pointer\n" );
+            return 0;
+        }
     }
     return 1;
 }
@@ -311,11 +319,6 @@ static int parse_spec_export( ORDDEF *odp, DLLSPEC *spec )
         error( "'stdcall' not supported for Win16\n" );
         return 0;
     }
-    if (!is_win32 && odp->type == TYPE_THISCALL)
-    {
-        error( "'thiscall' not supported for Win16\n" );
-        return 0;
-    }
     if (is_win32 && odp->type == TYPE_PASCAL)
     {
         error( "'pascal' not supported for Win32\n" );
@@ -327,6 +330,9 @@ static int parse_spec_export( ORDDEF *odp, DLLSPEC *spec )
     if (odp->type == TYPE_VARARGS)
         odp->flags |= FLAG_NORELAY;  /* no relay debug possible for varags entry point */
 
+    if (target_cpu != CPU_x86)
+        odp->flags &= ~FLAG_THISCALL;
+
     if (!(token = GetToken(1)))
     {
         if (!strcmp( odp->name, "@" ))
@@ -349,7 +355,7 @@ static int parse_spec_export( ORDDEF *odp, DLLSPEC *spec )
             odp->flags |= FLAG_FORWARD;
         }
     }
-    if (target_cpu == CPU_x86 && odp->type == TYPE_THISCALL && !(odp->flags & FLAG_FORWARD))
+    if ((odp->flags & FLAG_THISCALL) && !(odp->flags & FLAG_FORWARD))
     {
         char *link_name = strmake( "__thiscall_%s", odp->link_name );
         free( odp->link_name );
@@ -506,6 +512,7 @@ static const char *parse_spec_flags( DLLSPEC *spec, ORDDEF *odp )
                     error( "Flag '%s' is not supported in Win32\n", FlagNames[i] );
                 break;
             case FLAG_RET64:
+            case FLAG_THISCALL:
                 if (spec->type == SPEC_WIN16)
                     error( "Flag '%s' is not supported in Win16\n", FlagNames[i] );
                 break;
@@ -538,8 +545,16 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec )
 
     if (odp->type >= TYPE_NBTYPES)
     {
-        error( "Expected type after ordinal, found '%s' instead\n", token );
-        goto error;
+        if (!strcmp( token, "thiscall" )) /* for backwards compatibility */
+        {
+            odp->type = TYPE_STDCALL;
+            odp->flags |= FLAG_THISCALL;
+        }
+        else
+        {
+            error( "Expected type after ordinal, found '%s' instead\n", token );
+            goto error;
+        }
     }
 
     if (!(token = GetToken(0))) goto error;
@@ -571,7 +586,6 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec )
     case TYPE_STDCALL:
     case TYPE_VARARGS:
     case TYPE_CDECL:
-    case TYPE_THISCALL:
         if (!parse_spec_export( odp, spec )) goto error;
         break;
     case TYPE_ABS:
diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c
index 3552eca..1b4e534 100644
--- a/tools/winebuild/spec32.c
+++ b/tools/winebuild/spec32.c
@@ -58,7 +58,6 @@ static inline int needs_relay( const ORDDEF *odp )
     {
     case TYPE_STDCALL:
     case TYPE_CDECL:
-    case TYPE_THISCALL:
         break;
     case TYPE_STUB:
         if (odp->u.func.nb_args != -1) break;
@@ -129,7 +128,7 @@ static void get_arg_string( ORDDEF *odp, char str[MAX_ARGUMENTS + 1] )
             break;
         }
     }
-    if (target_cpu == CPU_x86 && odp->type == TYPE_THISCALL) str[0] = 't';
+    if (odp->flags & FLAG_THISCALL) str[0] = 't';
 
     /* append return value */
     if (get_ptr_size() == 4 && (odp->flags & FLAG_RET64))
@@ -225,7 +224,7 @@ static void output_relay_debug( DLLSPEC *spec )
         switch (target_cpu)
         {
         case CPU_x86:
-            if (odp->type == TYPE_THISCALL)  /* add the this pointer */
+            if (odp->flags & FLAG_THISCALL)  /* add the this pointer */
             {
                 output( "\tpopl %%eax\n" );
                 output( "\tpushl %%ecx\n" );
@@ -246,7 +245,7 @@ static void output_relay_debug( DLLSPEC *spec )
 
             output( "\tcall *4(%%eax)\n" );
             output_cfi( ".cfi_adjust_cfa_offset -8" );
-            if (odp->type == TYPE_STDCALL || odp->type == TYPE_THISCALL)
+            if (odp->type == TYPE_STDCALL)
                 output( "\tret $%u\n", get_args_size( odp ));
             else
                 output( "\tret\n" );
@@ -392,7 +391,6 @@ void output_exports( DLLSPEC *spec )
         case TYPE_STDCALL:
         case TYPE_VARARGS:
         case TYPE_CDECL:
-        case TYPE_THISCALL:
             if (odp->flags & FLAG_FORWARD)
             {
                 output( "\t%s .L__wine_spec_forwards+%u\n", get_asm_ptr_keyword(), fwd_size );
@@ -953,7 +951,6 @@ void output_def_file( DLLSPEC *spec, int include_private )
             /* fall through */
         case TYPE_VARARGS:
         case TYPE_CDECL:
-        case TYPE_THISCALL:
             /* try to reduce output */
             if(strcmp(name, odp->link_name) || (odp->flags & FLAG_FORWARD))
                 output( "=%s", odp->link_name );
@@ -969,7 +966,8 @@ void output_def_file( DLLSPEC *spec, int include_private )
             else if (strcmp(name, odp->link_name)) /* try to reduce output */
             {
                 output( "=%s", odp->link_name );
-                if (!kill_at && target_cpu == CPU_x86) output( "@%d", at_param );
+                if (!kill_at && target_cpu == CPU_x86 && !(odp->flags & FLAG_THISCALL))
+                    output( "@%d", at_param );
             }
             break;
         }
diff --git a/tools/winebuild/winebuild.man.in b/tools/winebuild/winebuild.man.in
index 51ad544..4455e63 100644
--- a/tools/winebuild/winebuild.man.in
+++ b/tools/winebuild/winebuild.man.in
@@ -299,6 +299,12 @@ accessed through GetProcAddress.
 The entry point will be imported by ordinal instead of by name. The
 name is still exported.
 .TP
+.B -thiscall
+The function uses the
+.I thiscall
+calling convention (first parameter in %ecx register on i386).
+.TP
+.RE
 .BI -arch= cpu\fR[\fB,\fIcpu\fR]
 The entry point is only available on the specified CPU
 architecture(s). The names \fBwin32\fR and \fBwin64\fR match all
@@ -335,11 +341,6 @@ for a Win16 or Win32 function using the C calling convention
 .B varargs
 for a Win16 or Win32 function using the C calling convention with a
 variable number of arguments
-.TP
-.B thiscall
-for a Win32 function using the
-.I thiscall
-calling convention (first parameter in %ecx register on i386)
 .RE
 .PP
 .I args




More information about the wine-cvs mailing list