Commit 617839d5 authored by Alexandre Julliard's avatar Alexandre Julliard

Added varargs support for 16-bit entry points.

Added -ret16 entry point flag to allow 16-bit cdecl and varargs function to return 16-bit values too.
parent 4ff79add
...@@ -347,26 +347,19 @@ BOOL WINAPI IsDebuggerPresent(void) ...@@ -347,26 +347,19 @@ BOOL WINAPI IsDebuggerPresent(void)
/*********************************************************************** /***********************************************************************
* _DebugOutput (KERNEL.328) * _DebugOutput (KERNEL.328)
*/ */
void WINAPIV _DebugOutput( void ) void WINAPIV _DebugOutput( WORD flags, LPCSTR spec, VA_LIST16 valist )
{ {
VA_LIST16 valist;
WORD flags;
SEGPTR spec;
char caller[101]; char caller[101];
/* Decode caller address */ /* Decode caller address */
if (!GetModuleName16( GetExePtr(CURRENT_STACK16->cs), caller, sizeof(caller) )) if (!GetModuleName16( GetExePtr(CURRENT_STACK16->cs), caller, sizeof(caller) ))
sprintf( caller, "%04X:%04X", CURRENT_STACK16->cs, CURRENT_STACK16->ip ); sprintf( caller, "%04X:%04X", CURRENT_STACK16->cs, CURRENT_STACK16->ip );
/* Build debug message string */
VA_START16( valist );
flags = VA_ARG16( valist, WORD );
spec = VA_ARG16( valist, SEGPTR );
/* FIXME: cannot use wvsnprintf16 from kernel */ /* FIXME: cannot use wvsnprintf16 from kernel */
/* wvsnprintf16( temp, sizeof(temp), MapSL(spec), valist ); */ /* wvsnprintf16( temp, sizeof(temp), spec, valist ); */
/* Output */ /* Output */
FIXME("%s %04x %s\n", caller, flags, debugstr_a(MapSL(spec)) ); FIXME("%s %04x %s\n", caller, flags, debugstr_a(spec) );
} }
/*********************************************************************** /***********************************************************************
......
...@@ -267,7 +267,7 @@ ...@@ -267,7 +267,7 @@
325 pascal16 LogParamError(word ptr ptr) LogParamError16 325 pascal16 LogParamError(word ptr ptr) LogParamError16
326 pascal16 IsRomFile(word) IsRomFile16 326 pascal16 IsRomFile(word) IsRomFile16
327 pascal -register K327() HandleParamError 327 pascal -register K327() HandleParamError
328 pascal16 _DebugOutput() _DebugOutput 328 varargs -ret16 _DebugOutput(word str) _DebugOutput
329 pascal16 K329(str word) DebugFillBuffer 329 pascal16 K329(str word) DebugFillBuffer
332 variable THHOOK(0 0 0 0 0 0 0 0) 332 variable THHOOK(0 0 0 0 0 0 0 0)
334 pascal16 IsBadReadPtr(segptr word) IsBadReadPtr16 334 pascal16 IsBadReadPtr(segptr word) IsBadReadPtr16
......
...@@ -194,7 +194,7 @@ void RELAY_DebugCallFrom16( CONTEXT86 *context ) ...@@ -194,7 +194,7 @@ void RELAY_DebugCallFrom16( CONTEXT86 *context )
if (!call) return; /* happens for the two snoop register relays */ if (!call) return; /* happens for the two snoop register relays */
if (!RELAY_ShowDebugmsgRelay(funstr)) return; if (!RELAY_ShowDebugmsgRelay(funstr)) return;
DPRINTF( "%04lx:Call %s(",GetCurrentThreadId(),funstr); DPRINTF( "%04lx:Call %s(",GetCurrentThreadId(),funstr);
VA_START16( args16 ); args16 = (char *)(frame + 1);
if (call->lret == 0xcb66) /* cdecl */ if (call->lret == 0xcb66) /* cdecl */
{ {
...@@ -276,7 +276,6 @@ void RELAY_DebugCallFrom16( CONTEXT86 *context ) ...@@ -276,7 +276,6 @@ void RELAY_DebugCallFrom16( CONTEXT86 *context )
} }
DPRINTF( ") ret=%04x:%04x ds=%04x\n", frame->cs, frame->ip, frame->ds ); DPRINTF( ") ret=%04x:%04x ds=%04x\n", frame->cs, frame->ip, frame->ds );
VA_END16( args16 );
if (call->arg_types[0] & ARG_REGISTER) if (call->arg_types[0] & ARG_REGISTER)
DPRINTF(" AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n", DPRINTF(" AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
......
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
204 pascal ICClose(word) ICClose16 204 pascal ICClose(word) ICClose16
205 pascal ICSendMessage(word word long long) ICSendMessage16 205 pascal ICSendMessage(word word long long) ICSendMessage16
206 pascal16 ICOpenFunction(long long word segptr) ICOpenFunction16 206 pascal16 ICOpenFunction(long long word segptr) ICOpenFunction16
207 pascal _ICMessage() ICMessage16 207 varargs _ICMessage(word word word) ICMessage16
212 pascal ICGetInfo(word segptr long) ICGetInfo16 212 pascal ICGetInfo(word segptr long) ICGetInfo16
213 pascal16 ICLocate(long long ptr ptr word) ICLocate16 213 pascal16 ICLocate(long long ptr ptr word) ICLocate16
224 cdecl _ICCompress(word long segptr segptr segptr segptr segptr segptr long long long segptr segptr) ICCompress16 224 cdecl _ICCompress(word long segptr segptr segptr segptr segptr segptr long long long segptr segptr) ICCompress16
......
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
#include "msvideo_private.h" #include "msvideo_private.h"
#include "winver.h" #include "winver.h"
#include "winnls.h"
#include "vfw16.h" #include "vfw16.h"
#include "stackframe.h"
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(msvideo); WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
...@@ -139,23 +139,13 @@ LRESULT WINAPI ICClose16(HIC16 hic) ...@@ -139,23 +139,13 @@ LRESULT WINAPI ICClose16(HIC16 hic)
/*********************************************************************** /***********************************************************************
* _ICMessage [MSVIDEO.207] * _ICMessage [MSVIDEO.207]
*/ */
LRESULT VFWAPIV ICMessage16(void) LRESULT VFWAPIV ICMessage16( HIC16 hic, UINT16 msg, UINT16 cb, VA_LIST16 valist )
{ {
HIC16 hic;
UINT16 msg;
UINT16 cb;
LPWORD lpData; LPWORD lpData;
SEGPTR segData; SEGPTR segData;
LRESULT ret; LRESULT ret;
UINT16 i; UINT16 i;
VA_LIST16 valist;
VA_START16(valist);
hic = VA_ARG16(valist, HIC16);
msg = VA_ARG16(valist, UINT16);
cb = VA_ARG16(valist, UINT16);
lpData = HeapAlloc(GetProcessHeap(), 0, cb); lpData = HeapAlloc(GetProcessHeap(), 0, cb);
TRACE("0x%08lx, %u, %u, ...)\n", (DWORD) hic, msg, cb); TRACE("0x%08lx, %u, %u, ...)\n", (DWORD) hic, msg, cb);
...@@ -165,7 +155,6 @@ LRESULT VFWAPIV ICMessage16(void) ...@@ -165,7 +155,6 @@ LRESULT VFWAPIV ICMessage16(void)
lpData[i] = VA_ARG16(valist, WORD); lpData[i] = VA_ARG16(valist, WORD);
} }
VA_END16(valist);
segData = MapLS(lpData); segData = MapLS(lpData);
ret = ICSendMessage16(hic, msg, segData, (DWORD) cb); ret = ICSendMessage16(hic, msg, segData, (DWORD) cb);
UnMapLS(segData); UnMapLS(segData);
......
...@@ -113,7 +113,7 @@ LRESULT VFWAPI ICGetInfo16(HIC16,ICINFO16 *,DWORD); ...@@ -113,7 +113,7 @@ LRESULT VFWAPI ICGetInfo16(HIC16,ICINFO16 *,DWORD);
BOOL16 VFWAPI ICInfo16(DWORD,DWORD,ICINFO16 *); BOOL16 VFWAPI ICInfo16(DWORD,DWORD,ICINFO16 *);
HIC16 VFWAPI ICLocate16(DWORD,DWORD,LPBITMAPINFOHEADER, HIC16 VFWAPI ICLocate16(DWORD,DWORD,LPBITMAPINFOHEADER,
LPBITMAPINFOHEADER,WORD); LPBITMAPINFOHEADER,WORD);
LRESULT VFWAPIV ICMessage16(void); LRESULT VFWAPIV ICMessage16( HIC16 hic, UINT16 msg, UINT16 cb, VA_LIST16 valist );
HIC16 VFWAPI ICOpen16(DWORD,DWORD,UINT16); HIC16 VFWAPI ICOpen16(DWORD,DWORD,UINT16);
HIC16 VFWAPI ICOpenFunction16(DWORD,DWORD,UINT16,FARPROC16); HIC16 VFWAPI ICOpenFunction16(DWORD,DWORD,UINT16,FARPROC16);
LRESULT VFWAPI ICSendMessage16(HIC16,UINT16,DWORD,DWORD); LRESULT VFWAPI ICSendMessage16(HIC16,UINT16,DWORD,DWORD);
......
...@@ -387,7 +387,7 @@ ...@@ -387,7 +387,7 @@
416 pascal16 TrackPopupMenu(word word s_word s_word s_word word ptr) TrackPopupMenu16 416 pascal16 TrackPopupMenu(word word s_word s_word s_word word ptr) TrackPopupMenu16
417 pascal GetMenuCheckMarkDimensions() GetMenuCheckMarkDimensions 417 pascal GetMenuCheckMarkDimensions() GetMenuCheckMarkDimensions
418 pascal16 SetMenuItemBitmaps(word word word word word) SetMenuItemBitmaps16 418 pascal16 SetMenuItemBitmaps(word word word word word) SetMenuItemBitmaps16
420 pascal16 _wsprintf() wsprintf16 420 varargs -ret16 _wsprintf(ptr str) wsprintf16
421 pascal16 wvsprintf(ptr str ptr) wvsprintf16 421 pascal16 wvsprintf(ptr str ptr) wvsprintf16
422 pascal16 DlgDirSelectEx(word ptr word word) DlgDirSelectEx16 422 pascal16 DlgDirSelectEx(word ptr word word) DlgDirSelectEx16
423 pascal16 DlgDirSelectComboBoxEx(word ptr word word) DlgDirSelectComboBoxEx16 423 pascal16 DlgDirSelectComboBoxEx(word ptr word word) DlgDirSelectComboBoxEx16
......
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
#include "wine/winbase16.h" #include "wine/winbase16.h"
#include "wine/winuser16.h" #include "wine/winuser16.h"
#include "stackframe.h"
#include "wine/debug.h" #include "wine/debug.h"
...@@ -284,8 +283,7 @@ static UINT WPRINTF_GetLen( WPRINTF_FORMAT *format, WPRINTF_DATA *arg, ...@@ -284,8 +283,7 @@ static UINT WPRINTF_GetLen( WPRINTF_FORMAT *format, WPRINTF_DATA *arg,
/*********************************************************************** /***********************************************************************
* wvsnprintf16 (Not a Windows API) * wvsnprintf16 (Not a Windows API)
*/ */
static INT16 wvsnprintf16( LPSTR buffer, UINT16 maxlen, LPCSTR spec, static INT16 wvsnprintf16( LPSTR buffer, UINT16 maxlen, LPCSTR spec, VA_LIST16 args )
LPCVOID args )
{ {
WPRINTF_FORMAT format; WPRINTF_FORMAT format;
LPSTR p = buffer; LPSTR p = buffer;
...@@ -592,7 +590,7 @@ static INT wvsnprintfW( LPWSTR buffer, UINT maxlen, LPCWSTR spec, va_list args ) ...@@ -592,7 +590,7 @@ static INT wvsnprintfW( LPWSTR buffer, UINT maxlen, LPCWSTR spec, va_list args )
/*********************************************************************** /***********************************************************************
* wvsprintf (USER.421) * wvsprintf (USER.421)
*/ */
INT16 WINAPI wvsprintf16( LPSTR buffer, LPCSTR spec, LPCVOID args ) INT16 WINAPI wvsprintf16( LPSTR buffer, LPCSTR spec, VA_LIST16 args )
{ {
INT16 res; INT16 res;
...@@ -625,17 +623,11 @@ INT WINAPI wvsprintfW( LPWSTR buffer, LPCWSTR spec, va_list args ) ...@@ -625,17 +623,11 @@ INT WINAPI wvsprintfW( LPWSTR buffer, LPCWSTR spec, va_list args )
/*********************************************************************** /***********************************************************************
* _wsprintf (USER.420) * _wsprintf (USER.420)
*/ */
INT16 WINAPIV wsprintf16(void) INT16 WINAPIV wsprintf16( LPSTR buffer, LPCSTR spec, VA_LIST16 valist )
{ {
VA_LIST16 valist;
INT16 res; INT16 res;
SEGPTR buffer, spec;
VA_START16( valist ); res = wvsnprintf16( buffer, 1024, spec, valist );
buffer = VA_ARG16( valist, SEGPTR );
spec = VA_ARG16( valist, SEGPTR );
res = wvsnprintf16( MapSL(buffer), 1024, MapSL(spec), valist );
VA_END16( valist );
return ( res == -1 ) ? 1024 : res; return ( res == -1 ) ? 1024 : res;
} }
......
...@@ -73,15 +73,7 @@ typedef struct _STACK16FRAME ...@@ -73,15 +73,7 @@ typedef struct _STACK16FRAME
#define CURRENT_DS (CURRENT_STACK16->ds) #define CURRENT_DS (CURRENT_STACK16->ds)
/* varargs lists on the 16-bit stack */ /* varargs lists on the 16-bit stack */
typedef void *VA_LIST16;
#define __VA_ROUNDED16(type) \
((sizeof(type) + sizeof(WORD) - 1) / sizeof(WORD) * sizeof(WORD))
#define VA_START16(list) ((list) = (VA_LIST16)(CURRENT_STACK16 + 1)) #define VA_START16(list) ((list) = (VA_LIST16)(CURRENT_STACK16 + 1))
#define VA_ARG16(list,type) \
(((list) = (VA_LIST16)((char *)(list) + __VA_ROUNDED16(type))), \
*((type *)(void *)((char *)(list) - __VA_ROUNDED16(type))))
#define VA_END16(list) ((void)0) #define VA_END16(list) ((void)0)
......
...@@ -39,6 +39,14 @@ typedef UINT16 *LPUINT16; ...@@ -39,6 +39,14 @@ typedef UINT16 *LPUINT16;
#define MAKESEGPTR(seg,off) ((SEGPTR)MAKELONG(off,seg)) #define MAKESEGPTR(seg,off) ((SEGPTR)MAKELONG(off,seg))
typedef WORD *VA_LIST16;
#define __VA_ROUNDED16(type) \
((sizeof(type) + sizeof(WORD) - 1) / sizeof(WORD) * sizeof(WORD))
#define VA_ARG16(list,type) \
(((list) = (VA_LIST16)((char *)(list) + __VA_ROUNDED16(type))), \
*((type *)(void *)((char *)(list) - __VA_ROUNDED16(type))))
#define HFILE_ERROR16 ((HFILE16)-1) #define HFILE_ERROR16 ((HFILE16)-1)
#define DECLARE_HANDLE16(a) \ #define DECLARE_HANDLE16(a) \
......
...@@ -937,7 +937,7 @@ HWND16 WINAPI WindowFromDC16(HDC16); ...@@ -937,7 +937,7 @@ HWND16 WINAPI WindowFromDC16(HDC16);
HWND16 WINAPI WindowFromPoint16(POINT16); HWND16 WINAPI WindowFromPoint16(POINT16);
BOOL16 WINAPI WinHelp16(HWND16,LPCSTR,UINT16,DWORD); BOOL16 WINAPI WinHelp16(HWND16,LPCSTR,UINT16,DWORD);
UINT16 WINAPI WNetAddConnection16(LPCSTR,LPCSTR,LPCSTR); UINT16 WINAPI WNetAddConnection16(LPCSTR,LPCSTR,LPCSTR);
INT16 WINAPI wvsprintf16(LPSTR,LPCSTR,LPCVOID); INT16 WINAPI wvsprintf16(LPSTR,LPCSTR,VA_LIST16);
BOOL16 WINAPI DrawState16A(HDC16,HBRUSH16,DRAWSTATEPROC16,LPARAM,WPARAM16,INT16,INT16,INT16,INT16,UINT16); BOOL16 WINAPI DrawState16A(HDC16,HBRUSH16,DRAWSTATEPROC16,LPARAM,WPARAM16,INT16,INT16,INT16,INT16,UINT16);
BOOL16 WINAPI IsDialogMessage16(HWND16,MSG16*); BOOL16 WINAPI IsDialogMessage16(HWND16,MSG16*);
INT16 WINAPI GetCommError16(INT16,LPCOMSTAT16); INT16 WINAPI GetCommError16(INT16,LPCOMSTAT16);
......
...@@ -34,8 +34,7 @@ ...@@ -34,8 +34,7 @@
typedef enum typedef enum
{ {
TYPE_VARIABLE, /* variable */ TYPE_VARIABLE, /* variable */
TYPE_PASCAL_16, /* pascal function with 16-bit return (Win16) */ TYPE_PASCAL, /* pascal function (Win16) */
TYPE_PASCAL, /* pascal function with 32-bit return (Win16) */
TYPE_ABS, /* absolute value (Win16) */ TYPE_ABS, /* absolute value (Win16) */
TYPE_STUB, /* unimplemented stub */ TYPE_STUB, /* unimplemented stub */
TYPE_STDCALL, /* stdcall function (Win32) */ TYPE_STDCALL, /* stdcall function (Win32) */
...@@ -98,11 +97,12 @@ typedef struct ...@@ -98,11 +97,12 @@ typedef struct
/* entry point flags */ /* entry point flags */
#define FLAG_NORELAY 0x01 /* don't use relay debugging for this function */ #define FLAG_NORELAY 0x01 /* don't use relay debugging for this function */
#define FLAG_NONAME 0x02 /* don't import function by name */ #define FLAG_NONAME 0x02 /* don't import function by name */
#define FLAG_RET64 0x04 /* function returns a 64-bit value */ #define FLAG_RET16 0x04 /* function returns a 16-bit value */
#define FLAG_I386 0x08 /* function is i386 only */ #define FLAG_RET64 0x08 /* function returns a 64-bit value */
#define FLAG_REGISTER 0x10 /* use register calling convention */ #define FLAG_I386 0x10 /* function is i386 only */
#define FLAG_INTERRUPT 0x20 /* function is an interrupt handler */ #define FLAG_REGISTER 0x20 /* use register calling convention */
#define FLAG_PRIVATE 0x40 /* function is private (cannot be imported) */ #define FLAG_INTERRUPT 0x40 /* function is an interrupt handler */
#define FLAG_PRIVATE 0x80 /* function is private (cannot be imported) */
#define FLAG_FORWARD 0x100 /* function is a forwarded name */ #define FLAG_FORWARD 0x100 /* function is a forwarded name */
......
...@@ -44,7 +44,6 @@ static FILE *input_file; ...@@ -44,7 +44,6 @@ static FILE *input_file;
static const char * const TypeNames[TYPE_NBTYPES] = static const char * const TypeNames[TYPE_NBTYPES] =
{ {
"variable", /* TYPE_VARIABLE */ "variable", /* TYPE_VARIABLE */
"pascal16", /* TYPE_PASCAL_16 */
"pascal", /* TYPE_PASCAL */ "pascal", /* TYPE_PASCAL */
"equate", /* TYPE_ABS */ "equate", /* TYPE_ABS */
"stub", /* TYPE_STUB */ "stub", /* TYPE_STUB */
...@@ -58,6 +57,7 @@ static const char * const FlagNames[] = ...@@ -58,6 +57,7 @@ static const char * const FlagNames[] =
{ {
"norelay", /* FLAG_NORELAY */ "norelay", /* FLAG_NORELAY */
"noname", /* FLAG_NONAME */ "noname", /* FLAG_NONAME */
"ret16", /* FLAG_RET16 */
"ret64", /* FLAG_RET64 */ "ret64", /* FLAG_RET64 */
"i386", /* FLAG_I386 */ "i386", /* FLAG_I386 */
"register", /* FLAG_REGISTER */ "register", /* FLAG_REGISTER */
...@@ -212,14 +212,9 @@ static int ParseExportFunction( ORDDEF *odp ) ...@@ -212,14 +212,9 @@ static int ParseExportFunction( ORDDEF *odp )
error( "'stdcall' not supported for Win16\n" ); error( "'stdcall' not supported for Win16\n" );
return 0; return 0;
} }
if (odp->type == TYPE_VARARGS)
{
error( "'varargs' not supported for Win16\n" );
return 0;
}
break; break;
case SPEC_WIN32: case SPEC_WIN32:
if ((odp->type == TYPE_PASCAL) || (odp->type == TYPE_PASCAL_16)) if (odp->type == TYPE_PASCAL)
{ {
error( "'pascal' not supported for Win32\n" ); error( "'pascal' not supported for Win32\n" );
return 0; return 0;
...@@ -456,9 +451,18 @@ static int ParseOrdinal(int ordinal) ...@@ -456,9 +451,18 @@ static int ParseOrdinal(int ordinal)
if (odp->type >= TYPE_NBTYPES) if (odp->type >= TYPE_NBTYPES)
{ {
/* special case for backwards compatibility */
if (!strcmp( token, "pascal16" ))
{
odp->type = TYPE_PASCAL;
odp->flags |= FLAG_RET16;
}
else
{
error( "Expected type after ordinal, found '%s' instead\n", token ); error( "Expected type after ordinal, found '%s' instead\n", token );
goto error; goto error;
} }
}
if (!(token = GetToken(0))) goto error; if (!(token = GetToken(0))) goto error;
if (*token == '-' && !(token = ParseFlags( odp ))) goto error; if (*token == '-' && !(token = ParseFlags( odp ))) goto error;
...@@ -473,7 +477,6 @@ static int ParseOrdinal(int ordinal) ...@@ -473,7 +477,6 @@ static int ParseOrdinal(int ordinal)
case TYPE_VARIABLE: case TYPE_VARIABLE:
if (!ParseVariable( odp )) goto error; if (!ParseVariable( odp )) goto error;
break; break;
case TYPE_PASCAL_16:
case TYPE_PASCAL: case TYPE_PASCAL:
case TYPE_STDCALL: case TYPE_STDCALL:
case TYPE_VARARGS: case TYPE_VARARGS:
......
...@@ -250,7 +250,7 @@ static int BuildModule16( FILE *outfile, int max_code_offset, ...@@ -250,7 +250,7 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
{ {
case TYPE_CDECL: case TYPE_CDECL:
case TYPE_PASCAL: case TYPE_PASCAL:
case TYPE_PASCAL_16: case TYPE_VARARGS:
case TYPE_STUB: case TYPE_STUB:
selector = 1; /* Code selector */ selector = 1; /* Code selector */
break; break;
...@@ -344,12 +344,14 @@ static void BuildCallFrom16Func( FILE *outfile, const char *profile, const char ...@@ -344,12 +344,14 @@ static void BuildCallFrom16Func( FILE *outfile, const char *profile, const char
int short_ret = 0; int short_ret = 0;
int reg_func = 0; int reg_func = 0;
int usecdecl = 0; int usecdecl = 0;
int varargs = 0;
const char *args = profile + 7; const char *args = profile + 7;
char *ret_type; char *ret_type;
/* Parse function type */ /* Parse function type */
if (!strncmp( "c_", profile, 2 )) usecdecl = 1; if (!strncmp( "c_", profile, 2 )) usecdecl = 1;
else if (!strncmp( "v_", profile, 2 )) varargs = usecdecl = 1;
else if (strncmp( "p_", profile, 2 )) else if (strncmp( "p_", profile, 2 ))
{ {
fprintf( stderr, "Invalid function name '%s', ignored\n", profile ); fprintf( stderr, "Invalid function name '%s', ignored\n", profile );
...@@ -382,7 +384,8 @@ static void BuildCallFrom16Func( FILE *outfile, const char *profile, const char ...@@ -382,7 +384,8 @@ static void BuildCallFrom16Func( FILE *outfile, const char *profile, const char
ret_type = reg_func? "void" : short_ret ? "unsigned short" : "unsigned int"; ret_type = reg_func? "void" : short_ret ? "unsigned short" : "unsigned int";
fprintf( outfile, "typedef %s (__stdcall *proc_%s_t)( ", ret_type, profile ); fprintf( outfile, "typedef %s (%s*proc_%s_t)( ",
ret_type, usecdecl ? "" : "__stdcall ", profile );
args = profile + 7; args = profile + 7;
for ( i = 0; args[i]; i++ ) for ( i = 0; args[i]; i++ )
{ {
...@@ -395,7 +398,7 @@ static void BuildCallFrom16Func( FILE *outfile, const char *profile, const char ...@@ -395,7 +398,7 @@ static void BuildCallFrom16Func( FILE *outfile, const char *profile, const char
case 'p': case 't': fprintf( outfile, "void *" ); break; case 'p': case 't': fprintf( outfile, "void *" ); break;
} }
} }
if ( reg_func ) if (reg_func || varargs)
fprintf( outfile, "%svoid *", i? ", " : "" ); fprintf( outfile, "%svoid *", i? ", " : "" );
else if ( !i ) else if ( !i )
fprintf( outfile, "void" ); fprintf( outfile, "void" );
...@@ -447,6 +450,8 @@ static void BuildCallFrom16Func( FILE *outfile, const char *profile, const char ...@@ -447,6 +450,8 @@ static void BuildCallFrom16Func( FILE *outfile, const char *profile, const char
} }
if ( reg_func ) if ( reg_func )
fprintf( outfile, "%s context", i? ",\n" : "" ); fprintf( outfile, "%s context", i? ",\n" : "" );
else if (varargs)
fprintf( outfile, "%s args + %d", i? ",\n" : "", argsize );
fprintf( outfile, " );\n}\n\n" ); fprintf( outfile, " );\n}\n\n" );
} }
...@@ -459,10 +464,11 @@ static const char *get_function_name( const ORDDEF *odp ) ...@@ -459,10 +464,11 @@ static const char *get_function_name( const ORDDEF *odp )
static char buffer[80]; static char buffer[80];
sprintf( buffer, "%s_%s_%s", sprintf( buffer, "%s_%s_%s",
(odp->type == TYPE_CDECL) ? "c" : "p", (odp->type == TYPE_PASCAL) ? "p" :
(odp->type == TYPE_VARARGS) ? "v" : "c",
(odp->flags & FLAG_REGISTER) ? "regs" : (odp->flags & FLAG_REGISTER) ? "regs" :
(odp->flags & FLAG_INTERRUPT) ? "intr" : (odp->flags & FLAG_INTERRUPT) ? "intr" :
(odp->type == TYPE_PASCAL_16) ? "word" : "long", (odp->flags & FLAG_RET16) ? "word" : "long",
odp->u.func.arg_types ); odp->u.func.arg_types );
return buffer; return buffer;
} }
...@@ -476,23 +482,20 @@ static int Spec16TypeCompare( const void *e1, const void *e2 ) ...@@ -476,23 +482,20 @@ static int Spec16TypeCompare( const void *e1, const void *e2 )
const ORDDEF *odp1 = *(const ORDDEF **)e1; const ORDDEF *odp1 = *(const ORDDEF **)e1;
const ORDDEF *odp2 = *(const ORDDEF **)e2; const ORDDEF *odp2 = *(const ORDDEF **)e2;
int retval; int retval;
int type1 = odp1->type;
int type2 = odp2->type;
int type1 = (odp1->type == TYPE_CDECL) ? 0 if (type1 == TYPE_STUB) type1 = TYPE_CDECL;
: (odp1->type == TYPE_PASCAL_16) ? 1 : 2; if (type2 == TYPE_STUB) type2 = TYPE_CDECL;
int type2 = (odp2->type == TYPE_CDECL) ? 0 if ((retval = type1 - type2) != 0) return retval;
: (odp2->type == TYPE_PASCAL_16) ? 1 : 2;
if (odp1->flags & FLAG_REGISTER) type1 += 4; type1 = odp1->flags & (FLAG_RET16|FLAG_REGISTER|FLAG_INTERRUPT);
if (odp1->flags & FLAG_INTERRUPT) type1 += 8; type2 = odp2->flags & (FLAG_RET16|FLAG_REGISTER|FLAG_INTERRUPT);
if (odp2->flags & FLAG_REGISTER) type2 += 4;
if (odp2->flags & FLAG_INTERRUPT) type2 += 8;
retval = type1 - type2; if ((retval = type1 - type2) != 0) return retval;
if ( !retval )
retval = strcmp( odp1->u.func.arg_types, odp2->u.func.arg_types );
return retval; return strcmp( odp1->u.func.arg_types, odp2->u.func.arg_types );
} }
...@@ -598,7 +601,7 @@ void BuildSpec16File( FILE *outfile ) ...@@ -598,7 +601,7 @@ void BuildSpec16File( FILE *outfile )
{ {
case TYPE_CDECL: case TYPE_CDECL:
case TYPE_PASCAL: case TYPE_PASCAL:
case TYPE_PASCAL_16: case TYPE_VARARGS:
case TYPE_STUB: case TYPE_STUB:
typelist[nFuncs++] = odp; typelist[nFuncs++] = odp;
...@@ -638,7 +641,7 @@ void BuildSpec16File( FILE *outfile ) ...@@ -638,7 +641,7 @@ void BuildSpec16File( FILE *outfile )
{ {
case TYPE_CDECL: case TYPE_CDECL:
case TYPE_PASCAL: case TYPE_PASCAL:
case TYPE_PASCAL_16: case TYPE_VARARGS:
fprintf( outfile, "extern void %s();\n", odp->link_name ); fprintf( outfile, "extern void %s();\n", odp->link_name );
break; break;
default: default:
...@@ -682,7 +685,7 @@ void BuildSpec16File( FILE *outfile ) ...@@ -682,7 +685,7 @@ void BuildSpec16File( FILE *outfile )
int j, argsize = 0; int j, argsize = 0;
strcpy( profile, get_function_name( typelist[i] )); strcpy( profile, get_function_name( typelist[i] ));
if ( typelist[i]->type != TYPE_CDECL ) if ( typelist[i]->type == TYPE_PASCAL )
for ( arg = typelist[i]->u.func.arg_types; *arg; arg++ ) for ( arg = typelist[i]->u.func.arg_types; *arg; arg++ )
switch ( *arg ) switch ( *arg )
{ {
...@@ -717,13 +720,13 @@ void BuildSpec16File( FILE *outfile ) ...@@ -717,13 +720,13 @@ void BuildSpec16File( FILE *outfile )
arg_types[j / 10] |= type << (3 * (j % 10)); arg_types[j / 10] |= type << (3 * (j % 10));
} }
if (typelist[i]->flags & (FLAG_REGISTER|FLAG_INTERRUPT)) arg_types[0] |= ARG_REGISTER; if (typelist[i]->flags & (FLAG_REGISTER|FLAG_INTERRUPT)) arg_types[0] |= ARG_REGISTER;
if (typelist[i]->type == TYPE_PASCAL_16) arg_types[0] |= ARG_RET16; if (typelist[i]->flags & FLAG_RET16) arg_types[0] |= ARG_RET16;
#ifdef __i386__ #ifdef __i386__
fprintf( outfile, " { 0x68, __wine_%s_CallFrom16_%s, 0x9a, __wine_call_from_16_%s,\n", fprintf( outfile, " { 0x68, __wine_%s_CallFrom16_%s, 0x9a, __wine_call_from_16_%s,\n",
make_c_identifier(dll_file_name), profile, make_c_identifier(dll_file_name), profile,
(typelist[i]->flags & (FLAG_REGISTER|FLAG_INTERRUPT)) ? "regs": (typelist[i]->flags & (FLAG_REGISTER|FLAG_INTERRUPT)) ? "regs":
typelist[i]->type == TYPE_PASCAL_16? "word" : "long" ); (typelist[i]->flags & FLAG_RET16) ? "word" : "long" );
if (argsize) if (argsize)
fprintf( outfile, " 0x%04x, 0xca66, %d, { 0x%08x, 0x%08x } },\n", fprintf( outfile, " 0x%04x, 0xca66, %d, { 0x%08x, 0x%08x } },\n",
code_selector, argsize, arg_types[0], arg_types[1] ); code_selector, argsize, arg_types[0], arg_types[1] );
...@@ -759,7 +762,7 @@ void BuildSpec16File( FILE *outfile ) ...@@ -759,7 +762,7 @@ void BuildSpec16File( FILE *outfile )
case TYPE_CDECL: case TYPE_CDECL:
case TYPE_PASCAL: case TYPE_PASCAL:
case TYPE_PASCAL_16: case TYPE_VARARGS:
case TYPE_STUB: case TYPE_STUB:
type = bsearch( &odp, typelist, nTypes, sizeof(ORDDEF *), Spec16TypeCompare ); type = bsearch( &odp, typelist, nTypes, sizeof(ORDDEF *), Spec16TypeCompare );
assert( type ); assert( type );
......
...@@ -225,6 +225,9 @@ only). ...@@ -225,6 +225,9 @@ only).
.B -noname .B -noname
The entry point will be imported by ordinal instead of by name. The entry point will be imported by ordinal instead of by name.
.TP .TP
.B -ret16
The function returns a 16-bit value (Win16 only).
.TP
.B -ret64 .B -ret64
The function returns a 64-bit value (Win32 only). The function returns a 64-bit value (Win32 only).
.TP .TP
...@@ -261,17 +264,21 @@ should be one of: ...@@ -261,17 +264,21 @@ should be one of:
.B stdcall .B stdcall
for a normal Win32 function for a normal Win32 function
.TP .TP
.B pascal
for a normal Win16 function
.TP
.B cdecl .B cdecl
for a Win32 function using the C calling convention for a Win16 or Win32 function using the C calling convention
.TP .TP
.B varargs .B varargs
for a Win32 function taking a variable number of arguments for a Win16 or Win32 function using the C calling convention with a
.TP variable number of arguments
.B pascal
for a Win16 function returning a 32-bit value
.TP .TP
.B pascal16 .B pascal16
for a Win16 function returning a 16-bit value. for a Win16 function returning a 16-bit value; this type is
deprecated, use
.B pascal -ret16
instead
.RE .RE
.PP .PP
.I args .I args
...@@ -331,13 +338,13 @@ shows how long lines can be split using a backslash: ...@@ -331,13 +338,13 @@ shows how long lines can be split using a backslash:
100 pascal CreateWindow(ptr ptr long s_word s_word s_word \\ 100 pascal CreateWindow(ptr ptr long s_word s_word s_word \\
s_word word word word ptr) WIN_CreateWindow s_word word word word ptr) WIN_CreateWindow
.PP .PP
To declare a function using a variable number of arguments in Win16, To declare a function using a variable number of arguments, specify
specify the function as taking no arguments. The arguments are then the function as
available with CURRENT_STACK16->args. In Win32, specify the function
as
.B varargs .B varargs
and declare it with a '...' parameter in the C file. See the and declare it in the C file with a '...' parameter for a Win32
wsprintf* functions in user.exe.spec and user32.spec for an example. function, or with an extra VA_LIST16 argument for a Win16 function.
See the wsprintf* functions in user.exe.spec and user32.spec for an
example.
.SS "Variable ordinals" .SS "Variable ordinals"
Syntax: Syntax:
.br .br
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment