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.
This commit is contained in:
parent
4ff79add63
commit
617839d522
|
@ -347,26 +347,19 @@ BOOL WINAPI IsDebuggerPresent(void)
|
|||
/***********************************************************************
|
||||
* _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];
|
||||
|
||||
/* Decode caller address */
|
||||
if (!GetModuleName16( GetExePtr(CURRENT_STACK16->cs), caller, sizeof(caller) ))
|
||||
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 */
|
||||
/* wvsnprintf16( temp, sizeof(temp), MapSL(spec), valist ); */
|
||||
/* wvsnprintf16( temp, sizeof(temp), spec, valist ); */
|
||||
|
||||
/* 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 @@
|
|||
325 pascal16 LogParamError(word ptr ptr) LogParamError16
|
||||
326 pascal16 IsRomFile(word) IsRomFile16
|
||||
327 pascal -register K327() HandleParamError
|
||||
328 pascal16 _DebugOutput() _DebugOutput
|
||||
328 varargs -ret16 _DebugOutput(word str) _DebugOutput
|
||||
329 pascal16 K329(str word) DebugFillBuffer
|
||||
332 variable THHOOK(0 0 0 0 0 0 0 0)
|
||||
334 pascal16 IsBadReadPtr(segptr word) IsBadReadPtr16
|
||||
|
|
|
@ -194,7 +194,7 @@ void RELAY_DebugCallFrom16( CONTEXT86 *context )
|
|||
if (!call) return; /* happens for the two snoop register relays */
|
||||
if (!RELAY_ShowDebugmsgRelay(funstr)) return;
|
||||
DPRINTF( "%04lx:Call %s(",GetCurrentThreadId(),funstr);
|
||||
VA_START16( args16 );
|
||||
args16 = (char *)(frame + 1);
|
||||
|
||||
if (call->lret == 0xcb66) /* cdecl */
|
||||
{
|
||||
|
@ -276,7 +276,6 @@ void RELAY_DebugCallFrom16( CONTEXT86 *context )
|
|||
}
|
||||
|
||||
DPRINTF( ") ret=%04x:%04x ds=%04x\n", frame->cs, frame->ip, frame->ds );
|
||||
VA_END16( args16 );
|
||||
|
||||
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",
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
204 pascal ICClose(word) ICClose16
|
||||
205 pascal ICSendMessage(word word long long) ICSendMessage16
|
||||
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
|
||||
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
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
#include "msvideo_private.h"
|
||||
#include "winver.h"
|
||||
#include "winnls.h"
|
||||
#include "vfw16.h"
|
||||
#include "stackframe.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
|
||||
|
@ -139,23 +139,13 @@ LRESULT WINAPI ICClose16(HIC16 hic)
|
|||
/***********************************************************************
|
||||
* _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;
|
||||
SEGPTR segData;
|
||||
LRESULT ret;
|
||||
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);
|
||||
|
||||
TRACE("0x%08lx, %u, %u, ...)\n", (DWORD) hic, msg, cb);
|
||||
|
@ -165,7 +155,6 @@ LRESULT VFWAPIV ICMessage16(void)
|
|||
lpData[i] = VA_ARG16(valist, WORD);
|
||||
}
|
||||
|
||||
VA_END16(valist);
|
||||
segData = MapLS(lpData);
|
||||
ret = ICSendMessage16(hic, msg, segData, (DWORD) cb);
|
||||
UnMapLS(segData);
|
||||
|
|
|
@ -113,7 +113,7 @@ LRESULT VFWAPI ICGetInfo16(HIC16,ICINFO16 *,DWORD);
|
|||
BOOL16 VFWAPI ICInfo16(DWORD,DWORD,ICINFO16 *);
|
||||
HIC16 VFWAPI ICLocate16(DWORD,DWORD,LPBITMAPINFOHEADER,
|
||||
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 ICOpenFunction16(DWORD,DWORD,UINT16,FARPROC16);
|
||||
LRESULT VFWAPI ICSendMessage16(HIC16,UINT16,DWORD,DWORD);
|
||||
|
|
|
@ -387,7 +387,7 @@
|
|||
416 pascal16 TrackPopupMenu(word word s_word s_word s_word word ptr) TrackPopupMenu16
|
||||
417 pascal GetMenuCheckMarkDimensions() GetMenuCheckMarkDimensions
|
||||
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
|
||||
422 pascal16 DlgDirSelectEx(word ptr word word) DlgDirSelectEx16
|
||||
423 pascal16 DlgDirSelectComboBoxEx(word ptr word word) DlgDirSelectComboBoxEx16
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
|
||||
#include "wine/winbase16.h"
|
||||
#include "wine/winuser16.h"
|
||||
#include "stackframe.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
|
@ -284,8 +283,7 @@ static UINT WPRINTF_GetLen( WPRINTF_FORMAT *format, WPRINTF_DATA *arg,
|
|||
/***********************************************************************
|
||||
* wvsnprintf16 (Not a Windows API)
|
||||
*/
|
||||
static INT16 wvsnprintf16( LPSTR buffer, UINT16 maxlen, LPCSTR spec,
|
||||
LPCVOID args )
|
||||
static INT16 wvsnprintf16( LPSTR buffer, UINT16 maxlen, LPCSTR spec, VA_LIST16 args )
|
||||
{
|
||||
WPRINTF_FORMAT format;
|
||||
LPSTR p = buffer;
|
||||
|
@ -592,7 +590,7 @@ static INT wvsnprintfW( LPWSTR buffer, UINT maxlen, LPCWSTR spec, va_list args )
|
|||
/***********************************************************************
|
||||
* wvsprintf (USER.421)
|
||||
*/
|
||||
INT16 WINAPI wvsprintf16( LPSTR buffer, LPCSTR spec, LPCVOID args )
|
||||
INT16 WINAPI wvsprintf16( LPSTR buffer, LPCSTR spec, VA_LIST16 args )
|
||||
{
|
||||
INT16 res;
|
||||
|
||||
|
@ -625,17 +623,11 @@ INT WINAPI wvsprintfW( LPWSTR buffer, LPCWSTR spec, va_list args )
|
|||
/***********************************************************************
|
||||
* _wsprintf (USER.420)
|
||||
*/
|
||||
INT16 WINAPIV wsprintf16(void)
|
||||
INT16 WINAPIV wsprintf16( LPSTR buffer, LPCSTR spec, VA_LIST16 valist )
|
||||
{
|
||||
VA_LIST16 valist;
|
||||
INT16 res;
|
||||
SEGPTR buffer, spec;
|
||||
|
||||
VA_START16( valist );
|
||||
buffer = VA_ARG16( valist, SEGPTR );
|
||||
spec = VA_ARG16( valist, SEGPTR );
|
||||
res = wvsnprintf16( MapSL(buffer), 1024, MapSL(spec), valist );
|
||||
VA_END16( valist );
|
||||
res = wvsnprintf16( buffer, 1024, spec, valist );
|
||||
return ( res == -1 ) ? 1024 : res;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,15 +73,7 @@ typedef struct _STACK16FRAME
|
|||
#define CURRENT_DS (CURRENT_STACK16->ds)
|
||||
|
||||
/* 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_ARG16(list,type) \
|
||||
(((list) = (VA_LIST16)((char *)(list) + __VA_ROUNDED16(type))), \
|
||||
*((type *)(void *)((char *)(list) - __VA_ROUNDED16(type))))
|
||||
#define VA_END16(list) ((void)0)
|
||||
|
||||
|
||||
|
|
|
@ -39,6 +39,14 @@ typedef UINT16 *LPUINT16;
|
|||
|
||||
#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 DECLARE_HANDLE16(a) \
|
||||
|
|
|
@ -937,7 +937,7 @@ HWND16 WINAPI WindowFromDC16(HDC16);
|
|||
HWND16 WINAPI WindowFromPoint16(POINT16);
|
||||
BOOL16 WINAPI WinHelp16(HWND16,LPCSTR,UINT16,DWORD);
|
||||
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 IsDialogMessage16(HWND16,MSG16*);
|
||||
INT16 WINAPI GetCommError16(INT16,LPCOMSTAT16);
|
||||
|
|
|
@ -34,8 +34,7 @@
|
|||
typedef enum
|
||||
{
|
||||
TYPE_VARIABLE, /* variable */
|
||||
TYPE_PASCAL_16, /* pascal function with 16-bit return (Win16) */
|
||||
TYPE_PASCAL, /* pascal function with 32-bit return (Win16) */
|
||||
TYPE_PASCAL, /* pascal function (Win16) */
|
||||
TYPE_ABS, /* absolute value (Win16) */
|
||||
TYPE_STUB, /* unimplemented stub */
|
||||
TYPE_STDCALL, /* stdcall function (Win32) */
|
||||
|
@ -98,11 +97,12 @@ typedef struct
|
|||
/* entry point flags */
|
||||
#define FLAG_NORELAY 0x01 /* don't use relay debugging for this function */
|
||||
#define FLAG_NONAME 0x02 /* don't import function by name */
|
||||
#define FLAG_RET64 0x04 /* function returns a 64-bit value */
|
||||
#define FLAG_I386 0x08 /* function is i386 only */
|
||||
#define FLAG_REGISTER 0x10 /* use register calling convention */
|
||||
#define FLAG_INTERRUPT 0x20 /* function is an interrupt handler */
|
||||
#define FLAG_PRIVATE 0x40 /* function is private (cannot be imported) */
|
||||
#define FLAG_RET16 0x04 /* function returns a 16-bit value */
|
||||
#define FLAG_RET64 0x08 /* function returns a 64-bit value */
|
||||
#define FLAG_I386 0x10 /* function is i386 only */
|
||||
#define FLAG_REGISTER 0x20 /* use register calling convention */
|
||||
#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 */
|
||||
|
||||
|
|
|
@ -44,7 +44,6 @@ static FILE *input_file;
|
|||
static const char * const TypeNames[TYPE_NBTYPES] =
|
||||
{
|
||||
"variable", /* TYPE_VARIABLE */
|
||||
"pascal16", /* TYPE_PASCAL_16 */
|
||||
"pascal", /* TYPE_PASCAL */
|
||||
"equate", /* TYPE_ABS */
|
||||
"stub", /* TYPE_STUB */
|
||||
|
@ -58,6 +57,7 @@ static const char * const FlagNames[] =
|
|||
{
|
||||
"norelay", /* FLAG_NORELAY */
|
||||
"noname", /* FLAG_NONAME */
|
||||
"ret16", /* FLAG_RET16 */
|
||||
"ret64", /* FLAG_RET64 */
|
||||
"i386", /* FLAG_I386 */
|
||||
"register", /* FLAG_REGISTER */
|
||||
|
@ -212,14 +212,9 @@ static int ParseExportFunction( ORDDEF *odp )
|
|||
error( "'stdcall' not supported for Win16\n" );
|
||||
return 0;
|
||||
}
|
||||
if (odp->type == TYPE_VARARGS)
|
||||
{
|
||||
error( "'varargs' not supported for Win16\n" );
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
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" );
|
||||
return 0;
|
||||
|
@ -455,10 +450,19 @@ static int ParseOrdinal(int ordinal)
|
|||
break;
|
||||
|
||||
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 );
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(token = GetToken(0))) goto error;
|
||||
if (*token == '-' && !(token = ParseFlags( odp ))) goto error;
|
||||
|
@ -473,7 +477,6 @@ static int ParseOrdinal(int ordinal)
|
|||
case TYPE_VARIABLE:
|
||||
if (!ParseVariable( odp )) goto error;
|
||||
break;
|
||||
case TYPE_PASCAL_16:
|
||||
case TYPE_PASCAL:
|
||||
case TYPE_STDCALL:
|
||||
case TYPE_VARARGS:
|
||||
|
|
|
@ -250,7 +250,7 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
|
|||
{
|
||||
case TYPE_CDECL:
|
||||
case TYPE_PASCAL:
|
||||
case TYPE_PASCAL_16:
|
||||
case TYPE_VARARGS:
|
||||
case TYPE_STUB:
|
||||
selector = 1; /* Code selector */
|
||||
break;
|
||||
|
@ -344,12 +344,14 @@ static void BuildCallFrom16Func( FILE *outfile, const char *profile, const char
|
|||
int short_ret = 0;
|
||||
int reg_func = 0;
|
||||
int usecdecl = 0;
|
||||
int varargs = 0;
|
||||
const char *args = profile + 7;
|
||||
char *ret_type;
|
||||
|
||||
/* Parse function type */
|
||||
|
||||
if (!strncmp( "c_", profile, 2 )) usecdecl = 1;
|
||||
else if (!strncmp( "v_", profile, 2 )) varargs = usecdecl = 1;
|
||||
else if (strncmp( "p_", profile, 2 ))
|
||||
{
|
||||
fprintf( stderr, "Invalid function name '%s', ignored\n", profile );
|
||||
|
@ -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";
|
||||
|
||||
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;
|
||||
for ( i = 0; args[i]; i++ )
|
||||
{
|
||||
|
@ -395,7 +398,7 @@ static void BuildCallFrom16Func( FILE *outfile, const char *profile, const char
|
|||
case 'p': case 't': fprintf( outfile, "void *" ); break;
|
||||
}
|
||||
}
|
||||
if ( reg_func )
|
||||
if (reg_func || varargs)
|
||||
fprintf( outfile, "%svoid *", i? ", " : "" );
|
||||
else if ( !i )
|
||||
fprintf( outfile, "void" );
|
||||
|
@ -447,6 +450,8 @@ static void BuildCallFrom16Func( FILE *outfile, const char *profile, const char
|
|||
}
|
||||
if ( reg_func )
|
||||
fprintf( outfile, "%s context", i? ",\n" : "" );
|
||||
else if (varargs)
|
||||
fprintf( outfile, "%s args + %d", i? ",\n" : "", argsize );
|
||||
fprintf( outfile, " );\n}\n\n" );
|
||||
}
|
||||
|
||||
|
@ -459,10 +464,11 @@ static const char *get_function_name( const ORDDEF *odp )
|
|||
static char buffer[80];
|
||||
|
||||
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_INTERRUPT) ? "intr" :
|
||||
(odp->type == TYPE_PASCAL_16) ? "word" : "long",
|
||||
(odp->flags & FLAG_RET16) ? "word" : "long",
|
||||
odp->u.func.arg_types );
|
||||
return buffer;
|
||||
}
|
||||
|
@ -476,23 +482,20 @@ static int Spec16TypeCompare( const void *e1, const void *e2 )
|
|||
const ORDDEF *odp1 = *(const ORDDEF **)e1;
|
||||
const ORDDEF *odp2 = *(const ORDDEF **)e2;
|
||||
int retval;
|
||||
int type1 = odp1->type;
|
||||
int type2 = odp2->type;
|
||||
|
||||
int type1 = (odp1->type == TYPE_CDECL) ? 0
|
||||
: (odp1->type == TYPE_PASCAL_16) ? 1 : 2;
|
||||
if (type1 == TYPE_STUB) type1 = TYPE_CDECL;
|
||||
if (type2 == TYPE_STUB) type2 = TYPE_CDECL;
|
||||
|
||||
int type2 = (odp2->type == TYPE_CDECL) ? 0
|
||||
: (odp2->type == TYPE_PASCAL_16) ? 1 : 2;
|
||||
if ((retval = type1 - type2) != 0) return retval;
|
||||
|
||||
if (odp1->flags & FLAG_REGISTER) type1 += 4;
|
||||
if (odp1->flags & FLAG_INTERRUPT) type1 += 8;
|
||||
if (odp2->flags & FLAG_REGISTER) type2 += 4;
|
||||
if (odp2->flags & FLAG_INTERRUPT) type2 += 8;
|
||||
type1 = odp1->flags & (FLAG_RET16|FLAG_REGISTER|FLAG_INTERRUPT);
|
||||
type2 = odp2->flags & (FLAG_RET16|FLAG_REGISTER|FLAG_INTERRUPT);
|
||||
|
||||
retval = type1 - type2;
|
||||
if ( !retval )
|
||||
retval = strcmp( odp1->u.func.arg_types, odp2->u.func.arg_types );
|
||||
if ((retval = type1 - type2) != 0) return retval;
|
||||
|
||||
return retval;
|
||||
return strcmp( odp1->u.func.arg_types, odp2->u.func.arg_types );
|
||||
}
|
||||
|
||||
|
||||
|
@ -598,7 +601,7 @@ void BuildSpec16File( FILE *outfile )
|
|||
{
|
||||
case TYPE_CDECL:
|
||||
case TYPE_PASCAL:
|
||||
case TYPE_PASCAL_16:
|
||||
case TYPE_VARARGS:
|
||||
case TYPE_STUB:
|
||||
typelist[nFuncs++] = odp;
|
||||
|
||||
|
@ -638,7 +641,7 @@ void BuildSpec16File( FILE *outfile )
|
|||
{
|
||||
case TYPE_CDECL:
|
||||
case TYPE_PASCAL:
|
||||
case TYPE_PASCAL_16:
|
||||
case TYPE_VARARGS:
|
||||
fprintf( outfile, "extern void %s();\n", odp->link_name );
|
||||
break;
|
||||
default:
|
||||
|
@ -682,7 +685,7 @@ void BuildSpec16File( FILE *outfile )
|
|||
int j, argsize = 0;
|
||||
|
||||
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++ )
|
||||
switch ( *arg )
|
||||
{
|
||||
|
@ -717,13 +720,13 @@ void BuildSpec16File( FILE *outfile )
|
|||
arg_types[j / 10] |= type << (3 * (j % 10));
|
||||
}
|
||||
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__
|
||||
fprintf( outfile, " { 0x68, __wine_%s_CallFrom16_%s, 0x9a, __wine_call_from_16_%s,\n",
|
||||
make_c_identifier(dll_file_name), profile,
|
||||
(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)
|
||||
fprintf( outfile, " 0x%04x, 0xca66, %d, { 0x%08x, 0x%08x } },\n",
|
||||
code_selector, argsize, arg_types[0], arg_types[1] );
|
||||
|
@ -759,7 +762,7 @@ void BuildSpec16File( FILE *outfile )
|
|||
|
||||
case TYPE_CDECL:
|
||||
case TYPE_PASCAL:
|
||||
case TYPE_PASCAL_16:
|
||||
case TYPE_VARARGS:
|
||||
case TYPE_STUB:
|
||||
type = bsearch( &odp, typelist, nTypes, sizeof(ORDDEF *), Spec16TypeCompare );
|
||||
assert( type );
|
||||
|
|
|
@ -225,6 +225,9 @@ only).
|
|||
.B -noname
|
||||
The entry point will be imported by ordinal instead of by name.
|
||||
.TP
|
||||
.B -ret16
|
||||
The function returns a 16-bit value (Win16 only).
|
||||
.TP
|
||||
.B -ret64
|
||||
The function returns a 64-bit value (Win32 only).
|
||||
.TP
|
||||
|
@ -261,17 +264,21 @@ should be one of:
|
|||
.B stdcall
|
||||
for a normal Win32 function
|
||||
.TP
|
||||
.B pascal
|
||||
for a normal Win16 function
|
||||
.TP
|
||||
.B cdecl
|
||||
for a Win32 function using the C calling convention
|
||||
for a Win16 or Win32 function using the C calling convention
|
||||
.TP
|
||||
.B varargs
|
||||
for a Win32 function taking a variable number of arguments
|
||||
.TP
|
||||
.B pascal
|
||||
for a Win16 function returning a 32-bit value
|
||||
for a Win16 or Win32 function using the C calling convention with a
|
||||
variable number of arguments
|
||||
.TP
|
||||
.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
|
||||
.PP
|
||||
.I args
|
||||
|
@ -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 \\
|
||||
s_word word word word ptr) WIN_CreateWindow
|
||||
.PP
|
||||
To declare a function using a variable number of arguments in Win16,
|
||||
specify the function as taking no arguments. The arguments are then
|
||||
available with CURRENT_STACK16->args. In Win32, specify the function
|
||||
as
|
||||
To declare a function using a variable number of arguments, specify
|
||||
the function as
|
||||
.B varargs
|
||||
and declare it with a '...' parameter in the C file. See the
|
||||
wsprintf* functions in user.exe.spec and user32.spec for an example.
|
||||
and declare it in the C file with a '...' parameter for a Win32
|
||||
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"
|
||||
Syntax:
|
||||
.br
|
||||
|
|
Loading…
Reference in New Issue