* harbour/include/hbcomp.h
* harbour/include/hbcompdf.h
* harbour/source/compiler/hbmain.c
* harbour/source/compiler/cmdcheck.c
* harbour/source/compiler/hbcomp.c
* harbour/source/compiler/genc.c
* harbour/source/compiler/harbour.yyc
* harbour/source/compiler/harbour.y
* harbour/source/compiler/hbdbginf.c
* harbour/source/compiler/genhrb.c
* harbour/source/compiler/gencobj.c
- removed old "AutoOpen" code used for @<name>.clp, SET PROCEDURE TO ...
and DO <func> [ WITH <args,...> ] statements
It was neither Clipper compatible not working correctly in some cases.
+ added new code for multi .prg module compilation into single unit
with support for multiple file wide declarations just like Cipper
does doe @.clp files and SET PROCEDURE TO / DO ... [ WITH ... ]
% cleaned redundant code used in harbour compiler to execute grammar
parser with different conditions. Now it's much shorter and simpler
and hb_compparse() is called only from one place.
! fixed possible multiple declarations in symbol table for ANNOUNCE
function
% rewritten C code generation to increase speed and make it independent
from some internal compiler structures. Now it's shorter and faster
but it strongly uses scope attributes in symbol table so they have
to be properly set during compilation and new code for .c file
generation should help in their validation.
% few other optimizations and cleanups
Now Harbour can compile code like:
/*** t01.prg ***/
static s_var := "main sVar"
proc main()
? procname(), "->", sVar
do t02
return
/*** t02.prg ***/
static s_var := "t02 sVar"
proc t02()
? procname(), "->", sVar
return
by simpe:
harbour -n -w -es2 t01
or using tst.clp:
t01
t02
and:
harbour -n -w -es2 @tst
in both cases it works just like Clipper. Please note that in the
second version generated file inherits (like in Clipper) name from
.clp file and is called "tst.c". The .clp file name is also used
as module handler signature.
TODO: add support for multiple static functions with the same name
but coming from different .prg modules compiled into single
unit using @.clp files or SET PROCEDURE TO / DO ... [ WITH ... ]
In above modifications I already implemented it partially but
I haven't made one very important extension which strongly
interacts with symbol table usage during compilation and can
be source of really bad problems if I made sth wrong so I plan
to finish when above changes will have been tested.
179 lines
5.6 KiB
C
179 lines
5.6 KiB
C
/*
|
|
* $Id$
|
|
*/
|
|
|
|
/*
|
|
* Harbour Project source code:
|
|
* Compiler Harbour Portable Object (.hrb) generation
|
|
*
|
|
* Copyright 1999 Eddie Runia <eddie@runia.com>
|
|
* www - http://www.harbour-project.org
|
|
*
|
|
* Copyright 2007 Przemyslaw Czerpak <druzus / at / priv.onet.pl>
|
|
* rewritten to work on memory buffers and with new compiler code
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit
|
|
* their web site at http://www.gnu.org/).
|
|
*
|
|
*/
|
|
|
|
#include "hbcomp.h"
|
|
|
|
#define SYM_NOLINK 0 /* symbol does not have to be linked */
|
|
#define SYM_FUNC 1 /* function defined in this module */
|
|
#define SYM_EXTERN 2 /* function defined in other module */
|
|
#define SYM_DEFERRED 3 /* lately bound function */
|
|
|
|
static ULONG hb_compHrbSize( HB_COMP_DECL, ULONG * pulSymbols, ULONG * pulFunctions )
|
|
{
|
|
PFUNCTION pFunc;
|
|
PCOMSYMBOL pSym;
|
|
ULONG ulSize;
|
|
|
|
* pulSymbols = * pulFunctions = 0;
|
|
|
|
/* count total size */
|
|
ulSize = 10; /* signature[4] + version[2] + symbols_number[4] */
|
|
pSym = HB_COMP_PARAM->symbols.pFirst;
|
|
while( pSym )
|
|
{
|
|
( * pulSymbols )++;
|
|
ulSize += strlen( pSym->szName ) + 3; /* \0 + symscope[1] + symtype[1] */
|
|
pSym = pSym->pNext;
|
|
}
|
|
ulSize += 4; /* functions_number[4] */
|
|
/* Generate functions data */
|
|
pFunc = HB_COMP_PARAM->functions.pFirst;
|
|
while( pFunc )
|
|
{
|
|
if( ( pFunc->funFlags & FUN_FILE_DECL ) == 0 )
|
|
{
|
|
( * pulFunctions )++;
|
|
ulSize += strlen( pFunc->szName ) + 5 + pFunc->lPCodePos; /* \0 + func_size[4] + function_body */
|
|
}
|
|
pFunc = pFunc->pNext;
|
|
}
|
|
|
|
return ulSize;
|
|
}
|
|
|
|
void hb_compGenBufPortObj( HB_COMP_DECL, BYTE ** pBufPtr, ULONG * pulSize )
|
|
{
|
|
PFUNCTION pFunc;
|
|
PCOMSYMBOL pSym;
|
|
ULONG ulSymbols, ulFunctions, ulLen;
|
|
BYTE * ptr;
|
|
|
|
* pulSize = hb_compHrbSize( HB_COMP_PARAM, &ulSymbols, &ulFunctions );
|
|
/* additional 0 byte is for passing buffer directly as string item */
|
|
ptr = * pBufPtr = ( BYTE * ) hb_xgrab( * pulSize + 1 );
|
|
|
|
/* signature */
|
|
*ptr++ = 0xC0;
|
|
*ptr++ = 'H';
|
|
*ptr++ = 'R';
|
|
*ptr++ = 'B';
|
|
HB_PUT_LE_UINT16( ptr, 2 ); /* version number */
|
|
ptr += 2;
|
|
|
|
HB_PUT_LE_UINT32( ptr, ulSymbols ); /* number of symbols */
|
|
ptr += 4;
|
|
/* generate the symbol table */
|
|
pSym = HB_COMP_PARAM->symbols.pFirst;
|
|
while( pSym )
|
|
{
|
|
ulLen = strlen( pSym->szName ) + 1;
|
|
memcpy( ptr, pSym->szName, ulLen );
|
|
ptr += ulLen;
|
|
/* TOFIX: this conversion strips upper byte from symbol scope
|
|
* Now we added workaround for it by using some strict
|
|
* bit order and restoring some others at runtime when
|
|
* .hrb file is loaded but we should create new format
|
|
* for .hrb files in which this field will have at least
|
|
* 16bit [druzus]
|
|
*/
|
|
*ptr++ = ( BYTE ) pSym->cScope;
|
|
/* symbol type */
|
|
/* if( hb_compFunctionFind( HB_COMP_PARAM, pSym->szName ) ) */
|
|
if( pSym->cScope & HB_FS_LOCAL )
|
|
*ptr++ = SYM_FUNC; /* function defined in this module */
|
|
else if( pSym->cScope & HB_FS_DEFERRED )
|
|
*ptr++ = SYM_DEFERRED; /* lately bound function */
|
|
else if( pSym->bFunc /* && hb_compFunCallFind( HB_COMP_PARAM, pSym->szName ) */ )
|
|
*ptr++ = SYM_EXTERN; /* external function */
|
|
else
|
|
*ptr++ = SYM_NOLINK; /* other symbol */
|
|
pSym = pSym->pNext;
|
|
}
|
|
|
|
HB_PUT_LE_UINT32( ptr, ulFunctions ); /* number of functions */
|
|
ptr += 4;
|
|
/* generate functions data */
|
|
pFunc = HB_COMP_PARAM->functions.pFirst;
|
|
while( pFunc )
|
|
{
|
|
if( ( pFunc->funFlags & FUN_FILE_DECL ) == 0 )
|
|
{
|
|
ulLen = strlen( pFunc->szName ) + 1;
|
|
memcpy( ptr, pFunc->szName, ulLen );
|
|
ptr += ulLen;
|
|
HB_PUT_LE_UINT32( ptr, pFunc->lPCodePos ); /* function size */
|
|
ptr += 4;
|
|
memcpy( ptr, pFunc->pCode, pFunc->lPCodePos ); /* function body */
|
|
ptr += pFunc->lPCodePos;
|
|
}
|
|
pFunc = pFunc->pNext;
|
|
}
|
|
}
|
|
|
|
void hb_compGenPortObj( HB_COMP_DECL, PHB_FNAME pFileName )
|
|
{
|
|
char szFileName[ HB_PATH_MAX ];
|
|
ULONG ulSize;
|
|
BYTE * pHrbBody;
|
|
FILE * yyc;
|
|
|
|
if( ! pFileName->szExtension )
|
|
pFileName->szExtension = ".hrb";
|
|
hb_fsFNameMerge( szFileName, pFileName );
|
|
|
|
yyc = hb_fopen( szFileName, "wb" );
|
|
if( ! yyc )
|
|
{
|
|
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_CREATE_OUTPUT, szFileName, NULL );
|
|
return;
|
|
}
|
|
|
|
if( ! HB_COMP_PARAM->fQuiet )
|
|
{
|
|
char buffer[ 80 + HB_PATH_MAX - 1 ];
|
|
hb_snprintf( buffer, sizeof( buffer ),
|
|
"Generating Harbour Portable Object source output to \'%s\'... ", szFileName );
|
|
hb_compOutStd( HB_COMP_PARAM, buffer );
|
|
}
|
|
|
|
hb_compGenBufPortObj( HB_COMP_PARAM, &pHrbBody, &ulSize );
|
|
|
|
if( fwrite( pHrbBody, ulSize, 1, yyc ) != 1 )
|
|
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_FILE_WRITE, szFileName, NULL );
|
|
|
|
hb_xfree( pHrbBody );
|
|
|
|
fclose( yyc );
|
|
|
|
if( ! HB_COMP_PARAM->fQuiet )
|
|
hb_compOutStd( HB_COMP_PARAM, "Done.\n" );
|
|
}
|