diff --git a/harbour/ChangeLog b/harbour/ChangeLog index cbac338ffe..ba23094ff9 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,7 @@ +19990525-19:15 CET Eddie Runia + * source/runner/runner.c; source/runner/run_exp.h; source/runner + created. currently in transition. + 19990525-15:40 CET Eddie Runia * bin, libs/b16, libs/b32, libs/vc, libs/icc, libs/win16 & libs/win32 added as per request diff --git a/harbour/source/runner/run_exp.h b/harbour/source/runner/run_exp.h new file mode 100644 index 0000000000..d3a8c909f2 --- /dev/null +++ b/harbour/source/runner/run_exp.h @@ -0,0 +1,239 @@ +/* + * + * This file contains the exportable functions available to the Harbour program + * + * Currently being discussed in 'Static initializers' + * + * If the discussion has finished, it can be removed from here. + * + */ +HARBOUR ARRAY(); +HARBOUR ASIZE(); +HARBOUR ATAIL(); +HARBOUR AINS(); +HARBOUR ADEL(); +HARBOUR AFILL(); +HARBOUR ASCAN(); +HARBOUR AEVAL(); +HARBOUR ACOPY(); +HARBOUR ACLONE(); +HARBOUR __ACCEPT(); +HARBOUR OUTSTD(); +HARBOUR QQOUT(); +HARBOUR QOUT(); +HARBOUR ERRORSYS(); +HARBOUR ERRORNEW(); +HARBOUR EVAL(); +HARBOUR VALTYPE(); +HARBOUR ASORT(); +HARBOUR CLASSCREATE(); +HARBOUR CLASSADD(); +HARBOUR CLASSNAME(); +HARBOUR CLASSINSTANCE(); +HARBOUR ISMESSAGE(); +HARBOUR OSEND(); +HARBOUR CLASSMOD(); +HARBOUR CLASSDEL(); +HARBOUR OCLONE(); +HARBOUR STOD(); +HARBOUR HB_SETCENTURY(); +HARBOUR SET(); +HARBOUR OS(); +HARBOUR ERRORNEW(); +HARBOUR FOPEN(); +HARBOUR FCREATE(); +HARBOUR FREAD(); +HARBOUR FWRITE(); +HARBOUR FERROR(); +HARBOUR FCLOSE(); +HARBOUR FERASE(); +HARBOUR FRENAME(); +HARBOUR FSEEK(); +HARBOUR FILE(); +HARBOUR FREADSTR(); +HARBOUR BIN2I(); +HARBOUR BIN2L(); +HARBOUR BIN2W(); +HARBOUR I2BIN(); +HARBOUR L2BIN(); +HARBOUR W2BIN(); +HARBOUR EXP(); +HARBOUR LOG(); +HARBOUR MOD(); +HARBOUR ISDATA(); +HARBOUR ISMETHOD(); +HARBOUR AODATA(); +HARBOUR AOMETHOD(); +HARBOUR AOGET(); +HARBOUR AOSET(); +HARBOUR OADDMETHOD(); +HARBOUR OADDINLINE(); +HARBOUR OADDDATA(); +HARBOUR OMODMETHOD(); +HARBOUR OMODINLINE(); +HARBOUR ODELMETHOD(); +HARBOUR ODELINLINE(); +HARBOUR ODELDATA(); +HARBOUR DEFAULT(); +HARBOUR TOCHAR(); +HARBOUR HBDEBUG(); +HARBOUR ISALPHA(); +HARBOUR ISDIGIT(); +HARBOUR ISUPPER(); +HARBOUR ISLOWER(); +HARBOUR LTRIM(); +HARBOUR TRIM(); +HARBOUR ALLTRIM(); +HARBOUR PADR(); +HARBOUR PAD(); +HARBOUR PADL(); +HARBOUR PADC(); +HARBOUR RAT(); +HARBOUR RIGHT(); +HARBOUR SPACE(); +HARBOUR STUFF(); +HARBOUR STRTRAN(); +HARBOUR TCLASS(); +HARBOUR TRANSFORM(); +HARBOUR DATETIME(); +HARBOUR __ASTATIC(); +HARBOUR __STATIC(); +HARBOUR __GLOBALSTACKLEN(); +HARBOUR __AGLOBALSTACK(); +HARBOUR __STACKLEN(); +HARBOUR __ASTACK(); +HARBOUR __APARAM(); +HARBOUR ACOS(); +HARBOUR ASIN(); +HARBOUR ATAN(); +HARBOUR COS(); +HARBOUR COSH(); +HARBOUR LOG10(); +HARBOUR SIN(); +HARBOUR SINH(); +HARBOUR TAN(); +HARBOUR TANH(); +HARBOUR STRDUMP(); +HARBOUR STRTOKEN(); +HARBOUR ROT13(); +HARBOUR PVALUE(); + +/* Same story. + + All the function pointers of the internal functions + Including Runner itself, since the first symbol gets executed by Harbour ;-) +*/ + +static SYMBOL symbols[] = { +{ "HB_RUN", FS_PUBLIC, HB_RUN , 0 }, +{ "ARRAY", FS_PUBLIC, ARRAY , 0 }, +{ "ASIZE", FS_PUBLIC, ASIZE , 0 }, +{ "ATAIL", FS_PUBLIC, ATAIL , 0 }, +{ "AINS", FS_PUBLIC, AINS , 0 }, +{ "ADEL", FS_PUBLIC, ADEL , 0 }, +{ "AFILL", FS_PUBLIC, AFILL , 0 }, +{ "ASCAN", FS_PUBLIC, ASCAN , 0 }, +{ "AEVAL", FS_PUBLIC, AEVAL , 0 }, +{ "ACOPY", FS_PUBLIC, ACOPY , 0 }, +{ "ACLONE", FS_PUBLIC, ACLONE , 0 }, +{ "__ACCEPT", FS_PUBLIC, __ACCEPT , 0 }, +{ "OUTSTD", FS_PUBLIC, OUTSTD , 0 }, +{ "QQOUT", FS_PUBLIC, QQOUT , 0 }, +{ "QOUT", FS_PUBLIC, QOUT , 0 }, +{ "ERRORSYS", FS_PUBLIC, ERRORSYS , 0 }, +{ "ERRORNEW", FS_PUBLIC, ERRORNEW , 0 }, +{ "EVAL", FS_PUBLIC, EVAL , 0 }, +{ "VALTYPE", FS_PUBLIC, VALTYPE , 0 }, +{ "ASORT", FS_PUBLIC, ASORT , 0 }, +{ "CLASSCREATE", FS_PUBLIC, CLASSCREATE , 0 }, +{ "CLASSADD", FS_PUBLIC, CLASSADD , 0 }, +{ "CLASSNAME", FS_PUBLIC, CLASSNAME , 0 }, +{ "CLASSINSTANCE", FS_PUBLIC, CLASSINSTANCE , 0 }, +{ "ISMESSAGE", FS_PUBLIC, ISMESSAGE , 0 }, +{ "OSEND", FS_PUBLIC, OSEND , 0 }, +{ "CLASSMOD", FS_PUBLIC, CLASSMOD , 0 }, +{ "CLASSDEL", FS_PUBLIC, CLASSDEL , 0 }, +{ "OCLONE", FS_PUBLIC, OCLONE , 0 }, +{ "STOD", FS_PUBLIC, STOD , 0 }, +{ "HB_SETCENTURY", FS_PUBLIC, HB_SETCENTURY , 0 }, +{ "SET", FS_PUBLIC, SET , 0 }, +{ "OS", FS_PUBLIC, OS , 0 }, +{ "ERRORNEW", FS_PUBLIC, ERRORNEW , 0 }, +{ "FOPEN", FS_PUBLIC, FOPEN , 0 }, +{ "FCREATE", FS_PUBLIC, FCREATE , 0 }, +{ "FREAD", FS_PUBLIC, FREAD , 0 }, +{ "FWRITE", FS_PUBLIC, FWRITE , 0 }, +{ "FERROR", FS_PUBLIC, FERROR , 0 }, +{ "FCLOSE", FS_PUBLIC, FCLOSE , 0 }, +{ "FERASE", FS_PUBLIC, FERASE , 0 }, +{ "FRENAME", FS_PUBLIC, FRENAME , 0 }, +{ "FSEEK", FS_PUBLIC, FSEEK , 0 }, +{ "FILE", FS_PUBLIC, FILE , 0 }, +{ "FREADSTR", FS_PUBLIC, FREADSTR , 0 }, +{ "BIN2I", FS_PUBLIC, BIN2I , 0 }, +{ "BIN2L", FS_PUBLIC, BIN2L , 0 }, +{ "BIN2W", FS_PUBLIC, BIN2W , 0 }, +{ "I2BIN", FS_PUBLIC, I2BIN , 0 }, +{ "L2BIN", FS_PUBLIC, L2BIN , 0 }, +{ "W2BIN", FS_PUBLIC, W2BIN , 0 }, +{ "EXP", FS_PUBLIC, EXP , 0 }, +{ "LOG", FS_PUBLIC, LOG , 0 }, +{ "MOD", FS_PUBLIC, MOD , 0 }, +{ "ISDATA", FS_PUBLIC, ISDATA , 0 }, +{ "ISMETHOD", FS_PUBLIC, ISMETHOD , 0 }, +{ "AODATA", FS_PUBLIC, AODATA , 0 }, +{ "AOMETHOD", FS_PUBLIC, AOMETHOD , 0 }, +{ "AOGET", FS_PUBLIC, AOGET , 0 }, +{ "AOSET", FS_PUBLIC, AOSET , 0 }, +{ "OADDMETHOD", FS_PUBLIC, OADDMETHOD , 0 }, +{ "OADDINLINE", FS_PUBLIC, OADDINLINE , 0 }, +{ "OADDDATA", FS_PUBLIC, OADDDATA , 0 }, +{ "OMODMETHOD", FS_PUBLIC, OMODMETHOD , 0 }, +{ "OMODINLINE", FS_PUBLIC, OMODINLINE , 0 }, +{ "ODELMETHOD", FS_PUBLIC, ODELMETHOD , 0 }, +{ "ODELINLINE", FS_PUBLIC, ODELINLINE , 0 }, +{ "ODELDATA", FS_PUBLIC, ODELDATA , 0 }, +{ "DEFAULT", FS_PUBLIC, DEFAULT , 0 }, +{ "TOCHAR", FS_PUBLIC, TOCHAR , 0 }, +{ "HBDEBUG", FS_PUBLIC, HBDEBUG , 0 }, +{ "ISALPHA", FS_PUBLIC, ISALPHA , 0 }, +{ "ISDIGIT", FS_PUBLIC, ISDIGIT , 0 }, +{ "ISUPPER", FS_PUBLIC, ISUPPER , 0 }, +{ "ISLOWER", FS_PUBLIC, ISLOWER , 0 }, +{ "LTRIM", FS_PUBLIC, LTRIM , 0 }, +{ "TRIM", FS_PUBLIC, TRIM , 0 }, +{ "ALLTRIM", FS_PUBLIC, ALLTRIM , 0 }, +{ "PADR", FS_PUBLIC, PADR , 0 }, +{ "PAD", FS_PUBLIC, PAD , 0 }, +{ "PADL", FS_PUBLIC, PADL , 0 }, +{ "PADC", FS_PUBLIC, PADC , 0 }, +{ "RAT", FS_PUBLIC, RAT , 0 }, +{ "RIGHT", FS_PUBLIC, RIGHT , 0 }, +{ "SPACE", FS_PUBLIC, SPACE , 0 }, +{ "STUFF", FS_PUBLIC, STUFF , 0 }, +{ "STRTRAN", FS_PUBLIC, STRTRAN , 0 }, +{ "TCLASS", FS_PUBLIC, TCLASS , 0 }, +{ "TRANSFORM", FS_PUBLIC, TRANSFORM , 0 }, +{ "DATETIME", FS_PUBLIC, DATETIME , 0 }, +{ "__ASTATIC", FS_PUBLIC, __ASTATIC , 0 }, +{ "__STATIC", FS_PUBLIC, __STATIC , 0 }, +{ "__GLOBALSTACKLEN", FS_PUBLIC, __GLOBALSTACKLEN, 0 }, +{ "__AGLOBALSTACK", FS_PUBLIC, __AGLOBALSTACK, 0 }, +{ "__STACKLEN", FS_PUBLIC, __STACKLEN , 0 }, +{ "__ASTACK", FS_PUBLIC, __ASTACK , 0 }, +{ "__APARAM", FS_PUBLIC, __APARAM , 0 }, +{ "ACOS", FS_PUBLIC, ACOS , 0 }, +{ "ASIN", FS_PUBLIC, ASIN , 0 }, +{ "ATAN", FS_PUBLIC, ATAN , 0 }, +{ "COS", FS_PUBLIC, COS , 0 }, +{ "COSH", FS_PUBLIC, COSH , 0 }, +{ "LOG10", FS_PUBLIC, LOG10 , 0 }, +{ "SIN", FS_PUBLIC, SIN , 0 }, +{ "SINH", FS_PUBLIC, SINH , 0 }, +{ "TAN", FS_PUBLIC, TAN , 0 }, +{ "TANH", FS_PUBLIC, TANH , 0 }, +{ "STRDUMP", FS_PUBLIC, STRDUMP , 0 }, +{ "STRTOKEN", FS_PUBLIC, STRTOKEN , 0 }, +{ "ROT13", FS_PUBLIC, ROT13 , 0 }, +{ "PVALUE", FS_PUBLIC, PVALUE , 0 } +}; diff --git a/harbour/source/runner/runner.c b/harbour/source/runner/runner.c new file mode 100644 index 0000000000..ac9c97e432 --- /dev/null +++ b/harbour/source/runner/runner.c @@ -0,0 +1,414 @@ +#include "pcode.h" + +#define FILE _FILE +#include + +/* #if INTEL32 */ +static BYTE prgFunction[] = { 0x68, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x00, 0x00, 0x00, 0x00, + 0xE8, 0x00, 0x00, 0x00, 0x00, + 0x83, 0xC4, 0x08, + 0xC3 }; + /* push offset pcode + push offset symbols + call near relative VirtualMachine + add esp, 8 + ret near */ + + /* This is the assembler output from : VirtualMachine(pcode,symbols). */ + +/* #elseif INTEL16 */ +/* #elseif MOTOROLA */ +/* #elseif ... */ +/* #endif */ + + +typedef union +{ + PBYTE pAsmData; /* The assembler bytes */ + HARBOURFUNC pFunPtr; /* The (dynamic) harbour function */ +} ASM_CALL, *PASM_CALL; + +typedef struct +{ + char *szName; /* Name of the function */ + PASM_CALL pAsmCall; /* Assembler call */ + PBYTE pCode; /* P-code */ +} DYNFUNC, *PDYNFUNC; + + +#define SYM_NOLINK 0 /* Symbol does not have to be linked */ +#define SYM_FUNC 1 /* Defined function */ +#define SYM_EXTERN 2 /* Previously defined function */ + +#define SYM_NOT_FOUND 0xFFFFFFFF /* Symbol not found. FindSymbol */ + +PASM_CALL CreateFun( PSYMBOL, PBYTE ); /* Create a dynamic function*/ +void Do( WORD ); +ULONG FindSymbol( char *, PDYNFUNC, ULONG ); +HARBOUR HB_RUN(); +void HRB_FileClose( _FILE * ); +void HRB_FileRead ( char *, int, int, FILE * ); +_FILE *HRB_FileOpen ( char * ); +void Push( PITEM ); +void PushNil( void ); +void PushSymbol( PSYMBOL ); +char *ReadId( FILE * ); +long ReadLong( FILE * ); + +#undef FILE +#include "run_exp.h" +#define FILE _FILE + +/* + * + * This file contains the exportable functions available to the Harbour program + * + * Currently being discussed in 'Static initializers' + * + * If the discussion has finished, it can be removed from here. + * + */ + +#include + +ULONG ulSymEntry = 0; /* Link enhancement */ + +/* + HB_Run alias TugBoat alias Runner. + + This program will get the data from the .HRB file and run the p-code + contained in it. + + In due time it should also be able to collect the data from the + binary/executable itself +*/ +HARBOUR HB_RUN( void ) /* HB_Run( ) */ +{ + char cLong[4]; /* Temporary long */ + char *szFileName; + char *szTemp; /* Temporary buffer */ + char *szIdx; + + FILE *file; + + ULONG ulSymbols; /* Number of symbols */ + ULONG ulFuncs; /* Number of functions */ + ULONG ulSize; /* Size of function */ + ULONG ul, ulPos; + + int i; + + BYTE bCont; + + PSYMBOL pSymRead; /* Symbols read */ + PDYNFUNC pDynFunc; /* Functions read */ + PDYNSYM pDynSym; + + if( _pcount() == 0 ) + printf( "\nPlease give HRB file name\n" ); + else + { + szFileName = _parc( 1 ); + file = HRB_FileOpen( szFileName ); /* Open as binary */ + if( file ) + { + ulSymbols = ReadLong( file ); + pSymRead = _xgrab( ulSymbols * sizeof( SYMBOL ) ); + + szTemp = _xgrab( 256 ); /* Must be enough for now */ + + for( ul=0; ul < ulSymbols; ul++) /* Read symbols in .HRB */ + { + pSymRead[ ul ].szName = ReadId( file ); + + HRB_FileRead( szTemp, 2, 1, file ); + + pSymRead[ ul ].cScope = szTemp[ 0 ]; + pSymRead[ ul ].pFunPtr = (void *) szTemp[ 1 ]; + pSymRead[ ul ].pDynSym = NULL; + } + + ulFuncs = ReadLong( file ); /* Read number of functions */ + pDynFunc = ( PDYNFUNC ) _xgrab( ulFuncs * sizeof( DYNFUNC ) ); + for( ul=0; ul < ulFuncs; ul++) /* Read symbols in .HRB */ + { + pDynFunc[ ul ].szName = ReadId( file ); + + ulSize = ReadLong( file ) + 1; /* Read size of function */ + pDynFunc[ ul ].pCode = _xgrab( ulSize ); + HRB_FileRead( pDynFunc[ ul ].pCode, 1, ulSize, file ); + /* Read the block */ + + pDynFunc[ ul ].pAsmCall = CreateFun( pSymRead, + pDynFunc[ ul ].pCode ); + /* Create matching dynamic */ + /* function */ + } + + ulSymEntry = 0; + for( ul = 0; ul < ulSymbols; ul++ ) /* Linker */ + { + if( ( (ULONG) pSymRead[ ul ].pFunPtr ) == SYM_FUNC ) + { + ulPos = FindSymbol( pSymRead[ ul ].szName, pDynFunc, ulFuncs ); + if( ulPos != SYM_NOT_FOUND ) + pSymRead[ ul ].pFunPtr = pDynFunc[ ulPos ].pAsmCall->pFunPtr; + else + pSymRead[ ul ].pFunPtr = (void *) SYM_EXTERN; + } + if( ( (ULONG) pSymRead[ ul ].pFunPtr ) == SYM_EXTERN ) + { /* External function */ + pDynSym = FindDynSym( pSymRead[ ul ].szName ); + if( !pDynSym ) + { + printf( "\nUnknown or unregistered function '%s'.", + pSymRead[ ul ].szName ); + exit( 1 ); + } + pSymRead[ ul ].pFunPtr = pDynSym->pFunPtr; + } + } + + ProcessSymbols( pSymRead, ulSymbols ); + + for( ul = 0; ul < ulSymbols; ul++ ) /* Check INIT functions */ + { + if( pSymRead[ ul ].cScope & FS_INIT ) + { + PushSymbol( pSymRead + ul ); + PushNil(); + for( i = 0; i < (_pcount() - 1); i++ ) + Push( _param( i + 2, IT_ANY ) ); + /* Push other cmdline params*/ + Do( _pcount() - 1 ); /* Run init function */ + } + } + + PushSymbol( pSymRead ); + PushNil(); + for( i = 0; i < (_pcount() - 1); i++ ) + Push( _param( i + 2, IT_ANY ) ); /* Push other cmdline params*/ + Do( _pcount() - 1 ); /* Run the thing !!! */ + + for( ul = 0; ul < ulSymbols; ul++ ) /* Check EXIT functions */ + { + if( pSymRead[ ul ].cScope & FS_EXIT ) + { + PushSymbol( pSymRead + ul ); + PushNil(); + Do( 0 ); /* Run exit function */ + pSymRead[ ul ].cScope = pSymRead[ ul ].cScope & (~FS_EXIT); + /* Exit function cannot be handled by main() in hvm.c */ + } + } + + for( ul = 0; ul < ulFuncs; ul++ ) + { + _xfree( pDynFunc[ ul ].pAsmCall->pAsmData ); + _xfree( pDynFunc[ ul ].pAsmCall ); + _xfree( pDynFunc[ ul ].pCode ); + _xfree( pDynFunc[ ul ].szName ); + } + + for( ul = 0; ul < ulSymbols; ul++ ) + { + _xfree( pSymRead[ ul ].szName ); + } + + _xfree( pDynFunc ); + _xfree( szTemp ); + _xfree( pSymRead ); + HRB_FileClose( file ); + } + else + { + printf( "\nCannot open %s\n", szFileName ); + } + } +} + + +static ULONG FindSymbol( char *szName, PDYNFUNC pDynFunc, ULONG ulLoaded ) +{ + ULONG ulRet; + BYTE bFound; + + if( ( ulSymEntry < ulLoaded ) && /* Is it a normal list ? */ + !strcmp( szName, pDynFunc[ ulSymEntry ].szName ) ) + ulRet = ulSymEntry++; + else + { + bFound = FALSE; + ulRet = 0; + while( !bFound && ulRet < ulLoaded ) + { + if( !strcmp( szName, pDynFunc[ ulRet ].szName ) ) + bFound = TRUE; + else + ulRet++; + } + if( !bFound ) + ulRet = SYM_NOT_FOUND; + } + return( ulRet ); +} + + +/* ReadId + Read the next (zero terminated) identifier */ +char *ReadId( FILE *file ) +{ + char *szFileName; + char *szTemp; /* Temporary buffer */ + char *szIdx; + char *szRet; + + BYTE bCont = TRUE; + + szTemp = _xgrab( 256 ); + szIdx = szTemp; + do + { + HRB_FileRead( szIdx, 1, 1, file ); + if( *szIdx ) + szIdx++; + else + bCont = FALSE; + } while( bCont ); + + szRet = (char *) _xgrab( szIdx - szTemp + 1 ); + strcpy( szRet, szTemp ); + _xfree( szTemp ); + + return( szRet ); +} + + +long ReadLong( FILE *file ) +{ + char cLong[4]; /* Temporary long */ + + HRB_FileRead( cLong, 4, 1, file ); /* Read number of symbols */ + + if( cLong[3] ) /* Convert to long if ok */ + { + PITEM pError = _errNew(); + _errPutDescription(pError, "Error reading .HRB file"); + _errLaunch(pError); + _errRelease(pError); + return( NULL ); + } + else + return( ( (BYTE) cLong[0] ) + + ( (BYTE) cLong[1] ) * 0x100 + + ( (BYTE) cLong[2] ) * 0x10000 + + ( (BYTE) cLong[3] ) * 0x1000000 ); +} + + +/* HRB_FileRead + Controlled read from file. If errornous -> Break */ +static void HRB_FileRead( char *cBuffer, int iSize, int iCount, FILE *fStream ) +{ + if( iCount != (int) fread( cBuffer, iSize, iCount, fStream ) ) + { /* Read error */ + PITEM pError = _errNew(); + _errPutDescription(pError, "Error reading .HRB file"); + _errLaunch(pError); + _errRelease(pError); + exit(1); + } +} + + +/* HRB_FileOpen + Open an .HRB file */ +static FILE *HRB_FileOpen( char *szFileName ) +{ + return( fopen( szFileName, "rb" ) ); +} + + +/* HRB_FileClose + Close an .HRB file */ +static void HRB_FileClose( FILE *file ) +{ + fclose( file ); +} + + +/* Patch an address of the dynamic function */ +static void Patch( PBYTE pCode, ULONG ulOffset, void *Address ) +{ +/* #if 32 bits and low byte first */ + + pCode[ ulOffset ] = ( (ULONG) Address ) & 0xFF; + pCode[ ulOffset + 1 ] = ( (ULONG) Address >> 8 ) & 0xFF; + pCode[ ulOffset + 2 ] = ( (ULONG) Address >> 16 ) & 0xFF; + pCode[ ulOffset + 3 ] = ( (ULONG) Address >> 24 ) & 0xFF; + +/* #elseif 16 bits and low byte first */ +/* #elseif 32 bits and high byte first */ +/* #elseif ... */ +/* #endif */ +} + + +/* Intel specific ?? Patch an address relative to the next instruction */ +static void PatchRelative( PBYTE pCode, ULONG ulOffset, + void *Address, ULONG ulNext ) +{ +/* #if 32 bits and low byte first */ + ULONG ulBase = (ULONG) pCode + ulNext; + /* Relative to next instruction */ + ULONG ulRelative = (ULONG) Address - ulBase; + + pCode[ ulOffset ] = ( ulRelative ) & 0xFF; + pCode[ ulOffset + 1 ] = ( ulRelative >> 8 ) & 0xFF; + pCode[ ulOffset + 2 ] = ( ulRelative >> 16 ) & 0xFF; + pCode[ ulOffset + 3 ] = ( ulRelative >> 24 ) & 0xFF; + +/* #elseif 16 bits and low byte first */ +/* #elseif 32 bits and high byte first */ +/* #elseif ... */ +/* #endif */ +} + + +/* + Create dynamic function. + + This function is needed, since it will allow the existing strategy of + function pointers to work properly. + + For each Harbour function a little program calling the virtual machine + should be present (see : *.c) + + Since these programs no longer exists when using this system, they should + be create dynamically at run-time. + + If a .PRG contains 10 functions, 10 dynamic functions are created which + are all the same :-) except for 2 pointers. +*/ +static PASM_CALL CreateFun( PSYMBOL pSymbols, PBYTE pCode ) +{ + PASM_CALL asmRet = (PASM_CALL) _xgrab( sizeof( ASM_CALL ) ); + + asmRet->pAsmData = (PBYTE) _xgrab( sizeof( prgFunction ) ); + memcpy( asmRet->pAsmData, prgFunction, sizeof( prgFunction ) ); + /* Copy new assembler code in */ +/* #if INTEL32 */ + + Patch( asmRet->pAsmData, 1, pSymbols ); /* Insert pointer to testsym */ + Patch( asmRet->pAsmData, 6, pCode); /* Insert pointer to testcode */ + PatchRelative( asmRet->pAsmData, 11, &VirtualMachine, 15 ); + /* Insert pointer to VirtualMachine() */ + +/* #elseif INTEL16 */ +/* #elseif MOTOROLA */ +/* #elseif ... */ +/* #endif */ + return( asmRet ); +} +