readme for genwowit.exe

This tool generates two source files for wow32, wowit.c and wowit.h,
from the input file wow.it.  wow.it contains one pseudo-prototype
for each API we want to have an interpreted thunk for.  The program
converts these psuedo-prototypes into interpreted thunk byte streams
in wowit.c's InstrSwamp byte array, and entries in wowit.c's
IntThunkTable which point to the API and the thunk instruction stream.
The psuedo-prototypes can have two names separated by an equals sign,
indicating the 16-bit API name on the left is thunked to the 32-bit
API name on the right.

The bytecode instruction streams consist of 0 or more argument conversion
opcodes, which don't have the high bit (0x80) set, followed by a return
code conversion opcode, which does have the high bit set.

genwowit tries to keep InstrSwamp as small as possible by pointing
multiple interpreted thunks at the same instruction stream when they
share prototypes (args & retval types).  See for example below how
UpdateColors, StartPage, EndPage, and GetTextCharacterExtra all
use the first instruction stream because they all take a GDI handle
and return an int.

Further, genwowit will point into the middle of an existing instruction
stream if it contains the instruction stream it needs.  For example see
below how the wowit.c IntThunkTable GetRasterizerCaps entry points to
InstrSwamp + 0xb, which is 3 bytes into the instruction stream for
TextOut, because ignoring the first three TextOut args they have the
same prototype.

An example, here's a tiny wow.it and the wowit.h and wowit.c that result.

----- wow.it begin
INT   UpdateColors(HGDI);
INT   StartPage(HGDI);
INT   EndPage(HGDI);
DWORD GetFontData(HGDI, DWORD, DWORD, PTR, DWORD);
WORD  GetRasterizerCaps(PTR, INT);
WORD  IsGDIObject=GetObjectType(HGDI);
WORD  GetTextAlign(HGDI);
INT   GetTextCharacterExtra(HGDI);
INT   SetTextCharacterExtra(HGDI, INT);
DWORD GetTextColor(HGDI);
INT   GetTextFace(HGDI, INT, PTR);
INT   SetTextJustification(HGDI, INT, INT);
WORD  TextOut(HGDI, INT, INT, PTR, INT);
----- wow.it end

here's the output genwowit produces on the console:

Generated wowit.h and wowit.c from wow.it
13 thunks, 8 unique instruction streams, 29 instruction bytes, 5 max args.

And the files:

----- wowit.h begin
//
// wowit.h generated by genwowit.exe from wow.it, DO NOT EDIT.
//

#include "intthunk.h"

#define MAX_IT_ARGS  5

#define IT_WORD                 ( (UCHAR) 0x0 )
#define IT_INT                  ( (UCHAR) 0x1 )
#define IT_DWORD                ( (UCHAR) 0x2 )
#define IT_LPDWORD              ( (UCHAR) 0x3 )
#define IT_PTR                  ( (UCHAR) 0x4 )
#define IT_PTRORATOM            ( (UCHAR) 0x5 )
#define IT_HGDI                 ( (UCHAR) 0x6 )
#define IT_HUSER                ( (UCHAR) 0x7 )
#define IT_COLOR                ( (UCHAR) 0x8 )
#define IT_HINST                ( (UCHAR) 0x9 )
#define IT_HICON                ( (UCHAR) 0xa )
#define IT_16ONLY               ( (UCHAR) 0xb )
#define IT_32ONLY               ( (UCHAR) 0xc )

#define IT_RETMASK              ( (UCHAR) 0x80 )
#define IT_DWORDRET             ( IT_RETMASK | (UCHAR) 0x0 )
#define IT_WORDRET              ( IT_RETMASK | (UCHAR) 0x1 )
#define IT_INTRET               ( IT_RETMASK | (UCHAR) 0x2 )
#define IT_HGDIRET              ( IT_RETMASK | (UCHAR) 0x3 )
#define IT_HUSERRET             ( IT_RETMASK | (UCHAR) 0x4 )
#define IT_ZERORET              ( IT_RETMASK | (UCHAR) 0x5 )
#define IT_HICONRET             ( IT_RETMASK | (UCHAR) 0x6 )
#define IT_ONERET               ( IT_RETMASK | (UCHAR) 0x7 )
#define IT_HPRNDWPRET           ( IT_RETMASK | (UCHAR) 0x8 )

#define ITID_UpdateColors                             0
#define ITID_StartPage                                1
#define ITID_EndPage                                  2
#define ITID_GetFontData                              3
#define ITID_GetRasterizerCaps                        4
#define ITID_IsGDIObject                              5
#define ITID_GetTextAlign                             6
#define ITID_GetTextCharacterExtra                    7
#define ITID_SetTextCharacterExtra                    8
#define ITID_GetTextColor                             9
#define ITID_GetTextFace                              10
#define ITID_SetTextJustification                     11
#define ITID_TextOut                                  12

#define ITID_MAX 12
----- wowit.h end

----- wowit.c begin
//
// wowit.c generated by genwowit.exe from wow.it, DO NOT EDIT.
//

#include "precomp.h"
#pragma hdrstop
#define WOWIT_C
#include "wowit.h"

CONST BYTE InstrSwamp[] = {
    /*   0  0x0   */ IT_HGDI, IT_INTRET, 
    /*   1  0x2   */ IT_HGDI, IT_DWORD, IT_DWORD, IT_PTR, IT_DWORD, IT_DWORDRET, 
    /*   2  0x8   */ IT_HGDI, IT_INT, IT_INT, IT_PTR, IT_INT, IT_WORDRET, 
    /*   3  0xe   */ IT_HGDI, IT_WORDRET, 
    /*   4  0x10  */ IT_HGDI, IT_INT, IT_INTRET, 
    /*   5  0x13  */ IT_HGDI, IT_DWORDRET, 
    /*   6  0x15  */ IT_HGDI, IT_INT, IT_PTR, IT_INTRET, 
    /*   7  0x19  */ IT_HGDI, IT_INT, IT_INT, IT_INTRET, 
};

INT_THUNK_TABLEENTRY IntThunkTable[] = {
    /*   0 */ { (FARPROC) UpdateColors,                    InstrSwamp + 0x0    },  /* 0 */ 
    /*   1 */ { (FARPROC) StartPage,                       InstrSwamp + 0x0    },  /* 0 */ 
    /*   2 */ { (FARPROC) EndPage,                         InstrSwamp + 0x0    },  /* 0 */ 
    /*   3 */ { (FARPROC) GetFontData,                     InstrSwamp + 0x2    },  /* 1 */ 
    /*   4 */ { (FARPROC) GetRasterizerCaps,               InstrSwamp + 0xb    },  /* 2 + 3 */ 
    /*   5 */ { (FARPROC) GetObjectType,                   InstrSwamp + 0xe    },  /* 3 */ 
    /*   6 */ { (FARPROC) GetTextAlign,                    InstrSwamp + 0xe    },  /* 3 */ 
    /*   7 */ { (FARPROC) GetTextCharacterExtra,           InstrSwamp + 0x0    },  /* 0 */ 
    /*   8 */ { (FARPROC) SetTextCharacterExtra,           InstrSwamp + 0x10   },  /* 4 */ 
    /*   9 */ { (FARPROC) GetTextColor,                    InstrSwamp + 0x13   },  /* 5 */ 
    /*  10 */ { (FARPROC) GetTextFace,                     InstrSwamp + 0x15   },  /* 6 */ 
    /*  11 */ { (FARPROC) SetTextJustification,            InstrSwamp + 0x19   },  /* 7 */ 
    /*  12 */ { (FARPROC) TextOut,                         InstrSwamp + 0x8    },  /* 2 */ 
};
----- wowit.c end
