diff --git a/harbour/genbuild.bat b/harbour/genbuild.bat new file mode 100644 index 0000000000..6f4158e4f5 --- /dev/null +++ b/harbour/genbuild.bat @@ -0,0 +1,2 @@ +cd.. +pkzip -r -p harb21-2 -x*.exe -x*.bak -x*.sim -x*.out -xsave.bat -xlexyy.c -xy_tab.c -xy_tab.h -x*.obj -x*.lib -x*.zip diff --git a/harbour/makefile.b32 b/harbour/makefile.b32 index abf1b8d513..ae9d23d1b8 100644 --- a/harbour/makefile.b32 +++ b/harbour/makefile.b32 @@ -1,5 +1,6 @@ # makefile for Borland C/C++ 32 bits +.path.asm = source\compiler .path.c = source\compiler;source\vm;source\rtl;source\tools .path.h = include .path.l = source\compiler @@ -14,7 +15,8 @@ PROJECT: harbour.lib libs\b32\terminal.lib libs\win32\terminal.lib harbour.exe harbour.lib : arrays.obj classes.obj codebloc.obj dates.obj datesx.obj \ debug.obj dynsym.obj environ.obj error.obj \ errorapi.obj errorsys.obj extend.obj files.obj itemapi.obj math.obj \ - mathx.obj set.obj strings.obj stringsx.obj strcmp.obj tclass.obj transfrm.obj + mathx.obj set.obj symbols.obj strings.obj stringsx.obj strcmp.obj \ + tclass.obj transfrm.obj libs\b32\terminal.lib : console.obj @@ -25,7 +27,9 @@ console.obj : console.c extend.h types.h tlib .\libs\b32\terminal.lib -+$@,, bcc32 -c -O2 -DWINDOWS -I.\include -o$@ source\rtl\console.c tlib .\libs\win32\terminal.lib -+$@,, - + +symbols.obj : symbols.asm + arrays.obj : arrays.c extend.h types.h classes.obj : classes.c extend.h types.h codebloc.obj : codebloc.c extend.h types.h @@ -53,6 +57,10 @@ error.c : error.prg harbour.exe errorsys.c : errorsys.prg harbour.exe tclass.c : tclass.prg harbour.exe +.asm.obj: + tasm $<, $@ + tlib .\libs\b32\harbour.lib -+$@,, + .prg.c: bin\harbour $< /n /osource\rtl @@ -60,12 +68,12 @@ tclass.c : tclass.prg harbour.exe bcc32 -c -O2 -I.\include -o$@ $< tlib .\libs\b32\harbour.lib -+$@,, -harbour.exe : y_tab.c lexyy.c harbour.obj +harbour.exe : y_tab.c lexyy.c genobj32.c compiler.h bcc32 -O2 -ebin\harbour.exe -Iinclude;source\compiler \ - source\compiler\y_tab.c source\compiler\lexyy.c \ - source\compiler\harbour.obj + source\compiler\y_tab.c source\compiler\lexyy.c source\compiler\genobj32.c del y_tab.obj del lexyy.obj + del compiler.obj y_tab.c : harbour.y bison -d -v -y -osource\compiler\y_tab.c source\compiler\harbour.y diff --git a/harbour/source/compiler/genobj32.c b/harbour/source/compiler/genobj32.c new file mode 100644 index 0000000000..dce74ef06d --- /dev/null +++ b/harbour/source/compiler/genobj32.c @@ -0,0 +1,692 @@ +#include +#include +#include +#include +#include +#include + +static void CompiledFileName( FILE * hObjFile, char * szFileName ); +static void CompilerVersion( FILE * hObjFile, char * szVersion ); +static void LocalNames( FILE * hObjFile, char * szNames[] ); +static void ExternalNames( FILE * hObjFile, char * szNames[] ); +static void Fixup( FILE * hObjFile, BYTE bType, WORD wOffset, BYTE bFlags, BYTE bSymbol ); +static void DefineSegment( FILE * hObjFile, BYTE bName, BYTE bClass, WORD wLen ); +static void PubDef( FILE * hObjFile, char * szName, WORD wSegment, WORD wOffset ); +static void EnumeratedData( FILE * hObjFile, BYTE bSegment, BYTE * pData, WORD wLen, WORD wOffset ); +static void GroupDef( FILE * hObjFile, BYTE bName, BYTE * aSegs ); +static void End( FILE * hObjFile ); + +static void CodeSegment( FILE * hObjFile, BYTE * prgCode, ULONG ulPrgLen, + WORD wFunctions ); +static void DataSegment( FILE * hObjFile, BYTE * symbol, WORD wSymLen, + WORD wSymbols, ULONG ulTotalSize ); + +static void GenerateLocalNames( FILE * hObjFile ); +static void GenerateExternals( FILE * hObjFile ); +static void GenerateCodeSegment( FILE * hObjFile ); +static void GenerateDataSegment( FILE * hObjFile ); +static void GenerateSymbolsSegment( FILE * hObjFile ); + +extern FUNCTIONS functions, funcalls; +extern SYMBOLS symbols; +extern int _iQuiet, _iStartProc; + +static BYTE prgFunction[] = { 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x83, 0xC4, 0x08, 0xC3 }; + +static char * * externNames = 0; +WORD wExternals = 1; /* _VirtualMachine is always added */ + +void GenObj32( char * szObjFileName, char * szFileName ) +{ + FILE * hObjFile; /* file handle for OBJ output */ + + if( ! ( hObjFile = fopen( szObjFileName, "wb" ) ) ) + { + printf( "Error opening file %s\n", szObjFileName ); + return; + } + + if( ! _iQuiet ) + printf( "\ngenerating Windows/Dos OBJ 32 bits..." ); + + CompiledFileName( hObjFile, szFileName ); + CompilerVersion( hObjFile, "Harbour" ); + GenerateLocalNames( hObjFile ); + GenerateExternals( hObjFile ); + GenerateCodeSegment( hObjFile ); + GenerateDataSegment( hObjFile ); + GenerateSymbolsSegment( hObjFile ); + End( hObjFile ); + + fclose( hObjFile ); + + if( ! _iQuiet ) + printf( "\n%s -> done!\n", szObjFileName ); +} + +static ULONG GetSymbolsSize( void ) +{ + return ( symbols.iCount - ( _iStartProc ? 0: 1 ) ) * sizeof( SYMBOL ); +} + +static PCOMSYMBOL GetFirstSymbol( void ) +{ + PCOMSYMBOL pSymbol = symbols.pFirst; + + if( ! _iStartProc ) + pSymbol = pSymbol->pNext; + + return pSymbol; +} + +static char * GetSymbolName( ULONG ulPos ) +{ + PCOMSYMBOL pSymbol = GetFirstSymbol(); + ULONG ul = 0; + + while( pSymbol && ( ul++ < ulPos ) ) + pSymbol = pSymbol->pNext; + + return pSymbol->szName; +} + +static ULONG GetPCodesSize( void ) +{ + ULONG ulTotal = 0; + PFUNCTION pFunction = functions.pFirst; + + if( ! _iStartProc ) + pFunction = pFunction->pNext; + + while( pFunction ) + { + ulTotal += pFunction->lPCodePos + 1; /* _ENDPROC !!! */ + pFunction = pFunction->pNext; + } + return ulTotal; +} + +ULONG GetSymbolsAmount( void ) +{ + PCOMSYMBOL pSymbol = GetFirstSymbol(); + ULONG ulAmount = 1; + + while( pSymbol->pNext ) + { + ulAmount++; + pSymbol = pSymbol->pNext; + } + return ulAmount; +} + +BOOL IsExternal( ULONG ulSymbol ) +{ + PCOMSYMBOL pSymbol = GetFirstSymbol(); + ULONG ul = 0; + + while( ul++ < ulSymbol ) + pSymbol = pSymbol->pNext; + + return ! GetFunction( pSymbol->szName ); +} + +WORD GetExternalPos( char * szExternal ) +{ + WORD w = 0; + + while( w < wExternals ) + { + if( ! strcmp( szExternal, externNames[ w ] ) ) + break; + w++; + } + + return w; +} + +static void GenerateLocalNames( FILE * hObjFile ) +{ + char * localNames[] = { "_TEXT", "CODE", "_DATA", "DATA", + "HB_SYMBOLS", "HB_STARTSYMBOLS", "HB_ENDSYMBOLS", "SYMGROUP", 0 }; + + LocalNames( hObjFile, localNames ); +} + +static void GenerateSymbolsSegment( FILE * hObjFile ) +{ + BYTE symbolsData[] = { 0, 0, 0, 0, 0, 0 }; + BYTE groupSegments[] = { 3, 4, 5, 0 }; /* segments order for HB_... */ + + DefineSegment( hObjFile, 7, 5, 0 ); /* 7 = HB_STARTSYMBOLS, 5 = DATA */ + DefineSegment( hObjFile, 6, /* "HB_SYMBOLS" position + 1 into localNames */ + 5, /* "DATA" position + 1 into localNames */ + 6 ); /* segment length */ + DefineSegment( hObjFile, 8, 5, 0 ); /* 8 = HB_ENDSYMBOLS, 5 = DATA */ + + GroupDef( hObjFile, 8, groupSegments ); /* 8 = "SYMGROUP" localNames position */ + + * ( WORD * ) symbolsData = GetSymbolsAmount(); + + EnumeratedData( hObjFile, 4, symbolsData, sizeof( symbolsData ), 0 ); /* 4 = HB_SYMBOLS defined segment */ + + Fixup( hObjFile, 0xE4, 2, 0x54, 2 ); /* Data: symbols location */ +} + +static void GenerateDataSegment( FILE * hObjFile ) +{ + SYMBOL symbol; + ULONG ulSize = GetSymbolsSize(); + PCOMSYMBOL pSymbol = GetFirstSymbol(); + ULONG ulSymbols = GetSymbolsAmount(), ul; + + while( pSymbol ) + { + ulSize += strlen( pSymbol->szName ) + 1; + pSymbol = pSymbol->pNext; + } + + ulSize += GetPCodesSize(); + + DefineSegment( hObjFile, 4, /* "_DATA" position + 1 into localNames */ + 5, /* "DATA" position + 1 into localNames */ + ulSize ); /* segment length */ + + memset( &symbol, 0, sizeof( symbol ) ); + DataSegment( hObjFile, &symbol, sizeof( symbol ), GetSymbolsAmount(), ulSize ); + + pSymbol = GetFirstSymbol(); + for( ul = 0; ul < ulSymbols; ul++ ) + { + Fixup( hObjFile, 0xE4, ( ul * sizeof( SYMBOL ) ), 0x54, 2 ); /* Data symbol name location */ + + if( IsExternal( ul ) ) + { + if( ! ( pSymbol->cScope & FS_MESSAGE ) ) + Fixup( hObjFile, 0xE4, ( ul * sizeof( SYMBOL ) ) + 5, 0x56, + GetExternalPos( GetSymbolName( ul ) ) + 1 ); + } + else + { + /* if( ! ( pSymbol->cScope & FS_MESSAGE ) ) */ + Fixup( hObjFile, 0xE4, ( ul * sizeof( SYMBOL ) ) + 5, 0x54, 1 ); /* function address location */ + } + pSymbol = pSymbol->pNext; + } +} + +static void GenerateCodeSegment( FILE * hObjFile ) +{ + WORD wFunctions = functions.iCount - ( _iStartProc ? 0: 1 ); + ULONG ulSize = wFunctions * sizeof( prgFunction ); + PFUNCTION pFunc = ( _iStartProc ? functions.pFirst: functions.pFirst->pNext ); + WORD w = 0; + + DefineSegment( hObjFile, 2, /* "_TEXT" position + 1 into localNames */ + 3, /* "CODE" position + 1 into localNames */ + ulSize ); /* segment length */ + + while( pFunc ) + { + if( !( pFunc->cScope & ( FS_STATIC | FS_INIT | FS_EXIT ) ) ) + PubDef( hObjFile, pFunc->szName, 1, w * sizeof( prgFunction ) ); + w++; + pFunc = pFunc->pNext; + } + + CodeSegment( hObjFile, prgFunction, sizeof( prgFunction ), wFunctions ); + + for( w = 0; w < wFunctions; w++ ) + { + /* prgFunction fixups */ + Fixup( hObjFile, 0xE4, ( w * sizeof( prgFunction ) ) + 1, + 0x54, 2 ); /* Data: symbols location */ + + Fixup( hObjFile, 0xE4, ( w * sizeof( prgFunction ) ) + 6, + 0x54, 2 ); /* Data pcode location */ + + Fixup( hObjFile, 0xA4, ( w * sizeof( prgFunction ) ) + 11, + 0x56, 1 ); /* External: _VirtualMachine */ + } +} + +static void GenerateExternals( FILE * hObjFile ) +{ + WORD w; + PFUNCTION pFunc, pFTemp; + + /* calculate amount of externals */ + pFunc = funcalls.pFirst; + while( pFunc ) + { + if( ! ( pFTemp = GetFunction( pFunc->szName ) ) || pFTemp == functions.pFirst ) + wExternals++; + pFunc = pFunc->pNext; + } + if( wExternals ) + { + externNames = ( char * * ) OurMalloc( sizeof( char * ) * ( wExternals + 2 ) ); + w = 1; + externNames[ 0 ] = "_VirtualMachine"; + + pFunc = funcalls.pFirst; + while( pFunc ) + { + if( ! ( pFTemp = GetFunction( pFunc->szName ) ) || pFTemp == functions.pFirst ) + externNames[ w++ ] = pFunc->szName; + pFunc = pFunc->pNext; + } + externNames[ w ] = 0; + ExternalNames( hObjFile, externNames ); + } +} + +static void putbyte( BYTE b, FILE * hObjFile ) +{ + fputc( b, hObjFile ); +} + +void putword( WORD w, FILE * hObjFile ) +{ + putbyte( LOBYTE( w ), hObjFile ); + putbyte( HIBYTE( w ), hObjFile ); +} + +static void CompiledFileName( FILE * hObjFile, char * szFileName ) +{ + WORD wLen = strlen( szFileName ); + BYTE bChk = 0; /* this is a checksum the linker will check to asure OBJ integrity */ + BYTE bChar; + + putbyte( 0x80, hObjFile ); /* this tells the linker the kind of OBJ record this is */ + bChk += 0x80; + + putbyte( 1 + 1 + wLen, hObjFile ); /* now it comes the total length of this OBJ record */ + bChk += ( 1 + 1 + wLen ); + putbyte( 0, hObjFile ); + + putbyte( wLen, hObjFile ); /* szFileName length */ + bChk += wLen; + + while( bChar = * szFileName++ ) + { + putbyte( bChar, hObjFile ); /* each of the szFileName characters */ + bChk += bChar; + } + + putbyte( 256 - bChk, hObjFile ); /* a checksum that will be recalculated by the linker */ +} + +static void CompilerVersion( FILE * hObjFile, char * szVersion ) +{ + WORD wLen = strlen( szVersion ); + BYTE bChk = 0; /* this is a checksum the linker will check to asure OBJ integrity */ + BYTE bChar; + + putbyte( 0x88, hObjFile ); /* this tells the linker the kind of OBJ record this is */ + bChk += 0x88; + + putword( 3 + wLen, hObjFile ); /* now it comes the total length of this OBJ record */ + bChk += LOBYTE( 3 + wLen ); + bChk += HIBYTE( 3 + wLen ); + + putword( 0, hObjFile ); + + while( bChar = * szVersion++ ) + { + putbyte( bChar, hObjFile ); /* each of the szFileName characters */ + bChk += bChar; + } + + putbyte( 256 - bChk, hObjFile ); /* a checksum that will be recalculated by the linker */ +} + +static void LocalNames( FILE * hObjFile, char * szNames[] ) +{ + BYTE b = 0, c; + WORD wTotalLen = 0; + BYTE bChk = 0; + BYTE bChar; + + while( szNames[ b ] ) + wTotalLen += strlen( szNames[ b++ ] ); + wTotalLen += 2 + b; + + putbyte( 0x96, hObjFile ); + bChk += 0x96; + + putbyte( LOBYTE( wTotalLen ), hObjFile ); + bChk += LOBYTE( wTotalLen ); + putbyte( HIBYTE( wTotalLen ), hObjFile ); + bChk += HIBYTE( wTotalLen ); + + putbyte( 0, hObjFile ); + + b = 0; + while( szNames[ b ] ) + { + putbyte( strlen( szNames[ b ] ), hObjFile ); + bChk += strlen( szNames[ b ] ); + + c = 0; + while( szNames[ b ][ c ] ) + { + putbyte( szNames[ b ][ c ], hObjFile ); + bChk += szNames[ b ][ c++ ]; + } + b++; + } + putbyte( 256 - bChk, hObjFile ); +} + +static void ExternalNames( FILE * hObjFile, char * szNames[] ) +{ + BYTE b = 0, c; + WORD wTotalLen = 0; + BYTE bChk = 0; + BYTE bChar; + + while( szNames[ b ] ) + wTotalLen += strlen( szNames[ b++ ] ) + 1; + wTotalLen += 2 + b - 1; + + putbyte( 0x8C, hObjFile ); + bChk += 0x8C; + + putword( wTotalLen, hObjFile ); + bChk += LOBYTE( wTotalLen ); + bChk += HIBYTE( wTotalLen ); + + b = 0; + while( szNames[ b ] ) + { + putbyte( strlen( szNames[ b ] ), hObjFile ); + bChk += strlen( szNames[ b ] ); + + c = 0; + + while( szNames[ b ][ c ] ) + { + putbyte( szNames[ b ][ c ], hObjFile ); + bChk += szNames[ b ][ c++ ]; + } + putbyte( 0, hObjFile ); + b++; + } + putbyte( 256 - bChk, hObjFile ); +} + +static void CodeSegment( FILE * hObjFile, BYTE * prgCode, ULONG ulPrgLen, WORD wFunctions ) +{ + BYTE bCheckSum = 0; + WORD y; + WORD wTotalLen = ( ulPrgLen * wFunctions ) + 4; + ULONG ul; + PFUNCTION pFunction = functions.pFirst; + ULONG ulPCodeOffset = ( symbols.iCount - ( _iStartProc ? 0: 1 ) ) * sizeof( SYMBOL ); + + if( ! _iStartProc ) + pFunction = pFunction->pNext; + + putbyte( 0xA0, hObjFile ); + bCheckSum += 0xA0; + + putword( wTotalLen, hObjFile ); + bCheckSum += LOBYTE( wTotalLen ); + bCheckSum += HIBYTE( wTotalLen ); + + putbyte( 1, hObjFile ); /* 1 = _TEXT segment */ + bCheckSum += 1; + + putword( 0, hObjFile ); /* 0 = offset */ + + for( y = 0; y < wFunctions; y++ ) + { + * ( ULONG * ) &prgCode[ 6 ] = ulPCodeOffset; /* function pcode offset */ + for( ul = 0; ul < ulPrgLen; ul++ ) + { + putbyte( * ( prgCode + ul ), hObjFile ); + bCheckSum += * ( prgCode + ul ); + } + ulPCodeOffset += pFunction->lPCodePos + 1; /* _ENDPROC !!! */ + pFunction = pFunction->pNext; + } + + putbyte( 256 - bCheckSum, hObjFile ); +} + +static void DataSegment( FILE * hObjFile, BYTE * symbol, WORD wSymLen, WORD wSymbols, + ULONG ulSize ) +{ + BYTE bCheckSum = 0; + WORD w, y; + WORD wTotalLen = 4 + ulSize; + PCOMSYMBOL pSymbol = GetFirstSymbol(); + PFUNCTION pFunction = functions.pFirst; + ULONG ulSymbolNameOffset = GetSymbolsSize() + GetPCodesSize(); + ULONG ulFunctionOffset; + + if( ! _iStartProc ) + pFunction = pFunction->pNext; + + putbyte( 0xA0, hObjFile ); + bCheckSum += 0xA0; + + putword( wTotalLen, hObjFile ); + bCheckSum += LOBYTE( wTotalLen ); + bCheckSum += HIBYTE( wTotalLen ); + + putbyte( 2, hObjFile ); /* 2 = _DATA segment */ + bCheckSum += 2; + + putword( 0, hObjFile ); /* 0 = offset */ + + for( y = 0; y < wSymbols; y++ ) + { + * ( ULONG * ) symbol = ulSymbolNameOffset; + + if( ! IsExternal( y ) ) + { + ulFunctionOffset = ( GetFunctionPos( pSymbol->szName ) - 1 ) * + sizeof( prgFunction ); + * ( ( ULONG * ) &symbol[ 5 ] ) = ulFunctionOffset; + } + else + * ( ( ULONG * ) &symbol[ 5 ] ) = 0; + + if( pSymbol->cScope == FS_MESSAGE ) + symbol[ 4 ] = FS_PUBLIC; + else + symbol[ 4 ] = pSymbol->cScope; + + for( w = 0; w < wSymLen; w++ ) + { + putbyte( * ( symbol + w ), hObjFile ); + bCheckSum += * ( symbol + w ); + } + + ulSymbolNameOffset += strlen( pSymbol->szName ) + 1; + pSymbol = pSymbol->pNext; + } + + while( pFunction ) + { + for( w = 0; w < pFunction->lPCodePos; w++ ) + { + putbyte( pFunction->pCode[ w ], hObjFile ); + bCheckSum += pFunction->pCode[ w ]; + } + putbyte( _ENDPROC, hObjFile ); + bCheckSum += _ENDPROC; + pFunction = pFunction->pNext; + } + + pSymbol = GetFirstSymbol(); + + while( pSymbol ) + { + for( w = 0; w < strlen( pSymbol->szName ); w++ ) + { + putbyte( pSymbol->szName[ w ], hObjFile ); + bCheckSum += pSymbol->szName[ w ]; + } + putbyte( 0, hObjFile ); + pSymbol = pSymbol->pNext; + } + + putbyte( 256 - bCheckSum, hObjFile ); +} + +static void DefineSegment( FILE * hObjFile, BYTE bName, BYTE bClass, WORD wLen ) +{ + BYTE bCheckSum = 0; + + putbyte( 0x98, hObjFile ); + bCheckSum += 0x98; + putbyte( 7, hObjFile ); /* SegDef records have always this length */ + bCheckSum += 7; + putbyte( 0, hObjFile ); + + putbyte( 0xA9, hObjFile ); + bCheckSum += 0xA9; + + putword( wLen, hObjFile ); + bCheckSum += LOBYTE( wLen ); + bCheckSum += HIBYTE( wLen ); + + putbyte( bName, hObjFile ); + bCheckSum += bName; + putbyte( bClass, hObjFile ); + bCheckSum += bClass; + putbyte( 0, hObjFile ); + + putbyte( 256 - bCheckSum, hObjFile ); +} + +static void PubDef( FILE * hObjFile, char * szName, WORD wSegment, WORD wOffset ) +{ + BYTE bChk = 0; + BYTE bChar; + WORD wLen = 2 + 2 + strlen( szName ) + 2 + 1; + + putbyte( 0x90, hObjFile ); + bChk += 0x90; + + putword( wLen, hObjFile ); + bChk += LOBYTE( wLen ); + bChk += HIBYTE( wLen ); + + putbyte( 0x00, hObjFile ); + putbyte( wSegment, hObjFile ); + bChk += wSegment; + + putbyte( strlen( szName ), hObjFile ); + bChk += strlen( szName ); + + while( bChar = * szName++ ) + { + putbyte( bChar, hObjFile ); + bChk += bChar; + } + + putword( wOffset, hObjFile); + bChk += LOBYTE( wOffset ); + bChk += HIBYTE( wOffset ); + putbyte( 0x00, hObjFile ); + + putbyte( 256 - bChk, hObjFile ); +} + +static void Fixup( FILE * hObjFile, BYTE bType, WORD wOffset, BYTE bFlags, BYTE bSymbol ) +{ + BYTE bCheckSum = 0; + + putbyte( 0x9D, hObjFile ); bCheckSum += 0x9D; + + putword( 5, hObjFile ); bCheckSum += 5; + + putbyte( bType + HIBYTE( wOffset ), hObjFile ); + bCheckSum += bType + HIBYTE( wOffset ); + + putbyte( LOBYTE( wOffset ), hObjFile ); + bCheckSum += LOBYTE( wOffset ); + + putbyte( bFlags, hObjFile ); bCheckSum += bFlags; + putbyte( bSymbol, hObjFile ); bCheckSum += bSymbol; + + putbyte( 256 - bCheckSum, hObjFile ); +} + +static void EnumeratedData( FILE * hObjFile, BYTE bSegment, BYTE * pData, WORD wLen, WORD wOffset ) +{ + BYTE bCheckSum = 0; + WORD w; + + putbyte( 0xA0, hObjFile ); + bCheckSum += 0xA0; + + putword( ( WORD ) ( wLen + 4 ), hObjFile ); + bCheckSum += LOBYTE( wLen + 4 ); + bCheckSum += HIBYTE( wLen + 4 ); + + putbyte( bSegment, hObjFile ); + bCheckSum += bSegment; + + putword( wOffset, hObjFile ); + bCheckSum += wOffset; + + for( w = 0; w < wLen; w++ ) + { + putbyte( * ( pData + w ), hObjFile ); + bCheckSum += * ( pData + w ); + } + + putbyte( 256 - bCheckSum, hObjFile ); +} + +static void End( FILE * hObjFile ) +{ + BYTE bChk = 0; + BYTE bChar; + + putbyte( 0x8A, hObjFile ); bChk += 0x8A; + + putbyte( 0x02, hObjFile ); bChk += 0x02; + putbyte( 0x00, hObjFile ); + + putbyte( 0x00, hObjFile ); bChk += 0x00; + + putbyte( 256 - bChk, hObjFile ); +} + +static void GroupDef( FILE * hObjFile, BYTE bName, BYTE * aSegs ) +{ + BYTE bCheckSum = 0; + WORD wRecLen = 2; + WORD w = 0; + + while( aSegs[ w++ ] ) + wRecLen += 2; + + putbyte( 0x9A, hObjFile ); + bCheckSum += 0x9A; + + putword( wRecLen, hObjFile ); + bCheckSum += LOBYTE( wRecLen ); + bCheckSum += HIBYTE( wRecLen ); + + putbyte( bName + 1, hObjFile ); + bCheckSum += bName + 1; + + w = 0; + while( aSegs[ w ] ) + { + putbyte( 0xFF, hObjFile ); + bCheckSum += 0xFF; + putbyte( aSegs[ w ], hObjFile ); + bCheckSum += aSegs[ w ]; + w++; + } + + putbyte( 256 - bCheckSum, hObjFile ); +} diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 226170eba7..7a9bd24ca2 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -16,6 +16,7 @@ #include /* required for allocating and freeing memory */ #include "pcode.h" /* pcode values */ #include "types.h" /* our defined types */ +#include "compiler.h" #ifdef __BORLANDC__ #define HAVE_STRUPR @@ -27,7 +28,7 @@ #endif /* TODO: #define this for various platforms */ -#define PATH_DELIMITER "/\\" +#define PATH_DELIMITER "\\" #define IS_PATH_SEP( c ) (strchr(PATH_DELIMITER, (c))!=NULL) extern FILE * yyin; /* currently yacc parsed file */ @@ -51,30 +52,6 @@ typedef struct int Include( char * szFileName ); /* end #include support */ -typedef struct _VAR /* locals, static, public variables support */ -{ - char *szName; /* variable name */ - char *szAlias; /* variable alias namespace */ - struct _VAR * pNext; /* pointer to next defined variable */ -} VAR, * PVAR; - -typedef struct __FUNC /* functions definition support */ -{ - char * szName; /* name of a defined Clipper function */ - char cScope; /* scope of a defined Clipper function */ - BYTE bFlags; /* some flags we may need */ - WORD wParamCount; /* number of declared parameters */ - PVAR pLocals; /* pointer to local variables list */ - PVAR pStatics; /* pointer to static variables list */ - PVAR pFields; /* pointer to fields variables list */ - BYTE * pCode; /* pointer to a memory block where pcode is stored */ - LONG lPCodeSize; /* total memory size for pcode */ - LONG lPCodePos; /* actual pcode offset */ - WORD wStaticsBase; /* base for this function statics */ - struct __FUNC * pOwner; /* pointer to the function/procedure that owns the codeblock */ - struct __FUNC * pNext; /* pointer to the next defined function */ -} _FUNC, * PFUNCTION; /* structure to hold a Clipper defined function */ - /* * flags for bFlags member */ @@ -83,30 +60,9 @@ typedef struct __FUNC /* functions definition support */ #define FUN_PROCEDURE 4 /* This is a procedure that shouldn't return value */ #define FUN_ILLEGAL_INIT 8 /* Attempt to initialize static variable with a function call */ -typedef struct -{ - PFUNCTION pFirst; /* pointer to the first defined funtion */ - PFUNCTION pLast; /* pointer to the last defined function */ - int iCount; /* number of defined functions */ -} FUNCTIONS; /* structure to control all Clipper defined functions */ - /* pcode chunks bytes size */ #define PCODE_CHUNK 100 -typedef struct _COMSYMBOL /* compiler symbol support structure */ -{ - char * szName; /* the name of the symbol */ - char cScope; /* the scope of the symbol */ - struct _COMSYMBOL * pNext; /* pointer to the next defined symbol */ -} COMSYMBOL, * PCOMSYMBOL; - -typedef struct /* symbol table support structures */ -{ - PCOMSYMBOL pFirst; /* pointer to the first defined symbol */ - PCOMSYMBOL pLast; /* pointer to the last defined symbol */ - int iCount; /* number of defined symbols */ -} SYMBOLS; - typedef struct __ELSEIF { WORD wOffset; @@ -181,7 +137,6 @@ void GenError( int, char*, char * ); /* generic parsing error management fu void GenExterns( void ); /* generates the symbols for the EXTERN names */ void GenReturn( WORD wOffset ); /* generates a return offset to later on fill it with the proper exiting pcode address */ PFUNCTION GetFuncall( char * szFunName ); /* locates a previously defined called function */ -PFUNCTION GetFunction( char * szFunName ); /* locates a previously defined function */ PVAR GetVar( PVAR pVars, WORD wOrder ); /* returns a variable if defined or zero */ WORD GetVarPos( PVAR pVars, char * szVarName ); /* returns the order + 1 of a variable if defined or zero */ int GetLocalVarPos( char * szVarName ); /* returns the order + 1 of a local variable */ @@ -226,15 +181,12 @@ void StaticDefStart( void ); void StaticDefEnd( WORD ); void StaticAssign( void ); /* checks if static variable is initialized with function call */ -void * OurMalloc( LONG lSize ); /* our malloc with error control */ -void * OurRealloc( void * p, LONG lSize ); /* our malloc with error control */ -#define OurFree( p ) free( (p) ); /* just for symetry -we can expand it later */ - /* output related functions */ void GenCCode( char *, char * ); /* generates the C language output */ void GenJava( char *, char * ); /* generates the Java language output */ void GenPascal( char *, char * ); /* generates the Pascal language output */ void GenRC( char *, char * ); /* generates the RC language output */ +void GenObj32( char *, char * ); /* generates OBJ 32 bits */ void PrintUsage( char * ); @@ -384,6 +336,7 @@ int _iSyntaxCheckOnly = 0; /* syntax check only */ int _iLanguage = LANG_C; /* default Harbour generated output language */ int _iRestrictSymbolLength = 0; /* generate 10 chars max symbols length */ int _iShortCuts = 1; /* .and. & .or. expressions shortcuts */ +int _iObj32 = 0; /* generate OBJ 32 bits */ WORD _wStatics = 0; /* number of defined statics variables on the PRG */ PRETURN pReturns = 0; /* list of multiple returns from a function */ PEXTERN pExterns = 0; @@ -989,7 +942,7 @@ void EXTERNAL_LINKAGE close_on_exit( void ) } } -int harbour_main( int argc, char * argv[] ) +int main( int argc, char * argv[] ) { int iStatus = 0, iArg = 1; char szFileName[ _POSIX_PATH_MAX ]; /* filename to parse */ @@ -1031,6 +984,16 @@ int harbour_main( int argc, char * argv[] ) } break; + case 'f': + case 'F': + { + char * szUpper = strupr( strdup( &argv[ iArg ][ 2 ] ) ); + if( ! strcmp( szUpper, "OBJ32" ) ) + _iObj32 = 1; + free( szUpper ); + } + break; + case 'g': case 'G': switch( argv[ iArg ][ 2 ] ) @@ -1143,7 +1106,7 @@ int harbour_main( int argc, char * argv[] ) fclose( yyin ); files.pLast =NULL; - if( ! _iSyntaxCheckOnly ) + if( ! _iSyntaxCheckOnly && ! _iObj32 ) { if( _pInitFunc ) { @@ -1189,6 +1152,12 @@ int harbour_main( int argc, char * argv[] ) break; } } + if( _iObj32 ) + { + pFileName->extension = ".obj"; + MakeFilename( szFileName, pFileName ); + GenObj32( szFileName, pFileName->name ); + } } else { @@ -1211,6 +1180,8 @@ void PrintUsage( char * szSelf ) printf( "Syntax: %s [options]\n" "\nOptions: \n" "\t/d[=]\t#define \n" + "\t/f\t\tgenerated object file\n" + "\t\t\t /fobj32 --> Windows/Dos 32 bits OBJ\n" "\t/g\t\tgenerated output language\n" "\t\t\t /gc (C default) --> \n" "\t\t\t /gj (Java) --> \n" @@ -1523,11 +1494,11 @@ int Include( char * szFileName ) pFile->pPrev = files.pLast; files.pLast = pFile; } -#ifdef __cplusplus +#ifdef __cplusplus yy_switch_to_buffer( (YY_BUFFER_STATE) pFile->pBuffer = yy_create_buffer( yyin, 8192 * 2 ) ); -#else +#else yy_switch_to_buffer( pFile->pBuffer = yy_create_buffer( yyin, 8192 * 2 ) ); -#endif +#endif files.iFiles++; return 1; } @@ -1545,19 +1516,19 @@ int yywrap( void ) /* handles the EOF of the currently processed file */ files.pLast = ( PFILE ) ( ( PFILE ) files.pLast )->pPrev; iLine = files.pLast->iLine; printf( "\nparsing file %s\n", files.pLast->szFileName ); -#ifdef __cplusplus +#ifdef __cplusplus yy_delete_buffer( (YY_BUFFER_STATE) ( ( PFILE ) pLast )->pBuffer ); #else yy_delete_buffer( ( ( PFILE ) pLast )->pBuffer ); -#endif +#endif free( pLast ); files.iFiles--; yyin = files.pLast->handle; -#ifdef __cplusplus +#ifdef __cplusplus yy_switch_to_buffer( (YY_BUFFER_STATE) files.pLast->pBuffer ); #else yy_switch_to_buffer( files.pLast->pBuffer ); -#endif +#endif return 0; /* we close the currently include file and continue */ } } @@ -1779,7 +1750,8 @@ void GenCCode( char *szFileName, char *szName ) /* generates the C languag { if( pFunc->cScope != FS_PUBLIC ) fprintf( yyc, "static " ); - fprintf( yyc, "HARBOUR %s( void )\n{\n static BYTE pcode[]={\n", pFunc->szName ); + + fprintf( yyc, "HARBOUR %s( void )\n{\n static BYTE pcode[] = { \n", pFunc->szName ); lPCodePos = 0; while( lPCodePos < pFunc->lPCodePos ) @@ -2605,6 +2577,29 @@ WORD GetSymbolPos( char * szSymbolName ) /* return 0 if not found or order + 1 * return 0; } +WORD GetFunctionPos( char * szFunctionName ) /* return 0 if not found or order + 1 */ +{ + PFUNCTION pFunc = functions.pFirst; + WORD wFunction = _iStartProc; + + while( pFunc ) + { + if( ! strcmp( pFunc->szName, szFunctionName ) && pFunc != functions.pFirst ) + return wFunction; + else + { + if( pFunc->pNext ) + { + pFunc = pFunc->pNext; + wFunction++; + } + else + return 0; + } + } + return 0; +} + void Inc( void ) { GenPCode1( _INC ); @@ -3012,9 +3007,8 @@ void SetFrame( void ) /* generates the proper _FRAME values */ */ void CodeBlockStart() { - PFUNCTION pFunc; + PFUNCTION pFunc = FunctionNew( NULL, FS_STATIC ); - pFunc =FunctionNew( NULL, FS_STATIC ); pFunc->pOwner = functions.pLast; pFunc->wStaticsBase = functions.pLast->wStaticsBase; diff --git a/harbour/source/compiler/symbols.asm b/harbour/source/compiler/symbols.asm new file mode 100644 index 0000000000..be2e96f5c6 --- /dev/null +++ b/harbour/source/compiler/symbols.asm @@ -0,0 +1,24 @@ +.386 + +HB_STARTSYMBOLS segment dword use32 public 'DATA' +HB_STARTSYMBOLS ends + +HB_SYMBOLS segment dword use32 public 'DATA' +HB_SYMBOLS ends + +HB_ENDSYMBOLS segment dword use32 public 'DATA' +HB_ENDSYMBOLS ends + +DGROUP group HB_STARTSYMBOLS, HB_SYMBOLS, HB_ENDSYMBOLS + + public _hb_firstsymbol, _hb_lastsymbol + +HB_STARTSYMBOLS segment + _hb_firstsymbol label byte +HB_STARTSYMBOLS ends + +HB_ENDSYMBOLS segment + _hb_lastsymbol label byte +HB_ENDSYMBOLS ends + + end