diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 5cc41a63da..426a2120f4 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,26 @@ +2000-07-15 20:00 UTC+0100 Ryszard Glab + + *include/hbexpra.c + *include/hbexprb.c + *include/hbexprc.c + *include/hbexprop.h + *source/common/expropt1.c + *source/common/expropt2.c + *source/compiler/harbour.l + *source/macro/macroa.c + *source/macro/macrob.c + *source/macro/macroc.c + * literal strings are now stored in the hash table together with + identifiers (only the main compiler not the macro compiler) + * expression of string type (created by the exression optimier) + stores info it is allowed to deallocate the memory occupied by + the string (normally it stores pointer to memory allocated + in the identifies table - however after optimization it can store + string allocated outside + + *source/compiler/hbident.c + * the hash table is increased to 373 items + 2000-07-14 22:40 UTC+0800 Ron Pinkas * source/compiler/harbour.slx ! Removed Todo: Hex Numbers. There are no more known TODOs. diff --git a/harbour/include/hbexpra.c b/harbour/include/hbexpra.c index 0a67bb8f0e..96f66ba214 100644 --- a/harbour/include/hbexpra.c +++ b/harbour/include/hbexpra.c @@ -281,23 +281,26 @@ HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR pName, HB_EXPR_PTR pParms ) { if( ( pArg->value.asNum.lVal % 256 ) == 0 && pArg->value.asNum.lVal != 0 ) { - pExpr->value.asString = ( char * ) HB_XGRAB( 1 ); - pExpr->value.asString[ 0 ] = '\0'; + pExpr->value.asString.string = ( char * ) HB_XGRAB( 1 ); + pExpr->value.asString.string[ 0 ] = '\0'; + pExpr->value.asString.dealloc = TRUE; pExpr->ulLength = 0; } else { - pExpr->value.asString = ( char * ) HB_XGRAB( 2 ); - pExpr->value.asString[ 0 ] = ( pArg->value.asNum.lVal % 256 ); - pExpr->value.asString[ 1 ] = '\0'; + pExpr->value.asString.string = ( char * ) HB_XGRAB( 2 ); + pExpr->value.asString.string[ 0 ] = ( pArg->value.asNum.lVal % 256 ); + pExpr->value.asString.string[ 1 ] = '\0'; + pExpr->value.asString.dealloc = TRUE; pExpr->ulLength = 1; } } else { - pExpr->value.asString = ( char * ) HB_XGRAB( 2 ); - pExpr->value.asString[ 0 ] = ( ( long ) pArg->value.asNum.dVal % 256 ); - pExpr->value.asString[ 1 ] = '\0'; + pExpr->value.asString.string = ( char * ) HB_XGRAB( 2 ); + pExpr->value.asString.string[ 0 ] = ( ( long ) pArg->value.asNum.dVal % 256 ); + pExpr->value.asString.string[ 1 ] = '\0'; + pExpr->value.asString.dealloc = TRUE; pExpr->ulLength = 1; } HB_EXPR_PCODE1( hb_compExprDelete, pParms ); @@ -325,6 +328,32 @@ HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR pName, HB_EXPR_PTR pParms ) return pExpr; } +/* In macro compiler strings should be automatically deallocated by + * the expression optimizer + * In harbour compiler strings are shared in the hash table then they + * cannot be deallocated by default +*/ +HB_EXPR_PTR hb_compExprNewString( char *szValue ) +{ + HB_EXPR_PTR pExpr; + + HB_TRACE(HB_TR_DEBUG, ("hb_compExprNewString(%s)", szValue)); + + pExpr =hb_compExprNew( HB_ET_STRING ); + + pExpr->value.asString.string = szValue; +#ifdef HB_MACRO_SUPPORT + pExpr->value.asString.dealloc = TRUE; +#else + pExpr->value.asString.dealloc = FALSE; +#endif + pExpr->ulLength = strlen( szValue ); + pExpr->ValType = HB_EV_STRING; + + return pExpr; +} + + /* Creates new array access expression * pArray[ pIndex ] * NOTE: In case of multiple indexes it is called recursively diff --git a/harbour/include/hbexprb.c b/harbour/include/hbexprb.c index 66848120c6..0ba573cde7 100644 --- a/harbour/include/hbexprb.c +++ b/harbour/include/hbexprb.c @@ -312,12 +312,12 @@ static HB_EXPR_FUNC( hb_compExprUseString ) break; case HB_EA_PUSH_PCODE: { - HB_EXPR_PCODE2( hb_compGenPushString, pSelf->value.asString, pSelf->ulLength ); + HB_EXPR_PCODE2( hb_compGenPushString, pSelf->value.asString.string, pSelf->ulLength ); #if !defined( HB_MACRO_SUPPORT ) /* only memvar variables are allowed in macro compilation - there is no * need to check for locals or static variables */ - if( hb_compExprCheckMacroVar( pSelf->value.asString ) ) + if( hb_compExprCheckMacroVar( pSelf->value.asString.string ) ) HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROTEXT ); #endif } @@ -329,7 +329,8 @@ static HB_EXPR_FUNC( hb_compExprUseString ) hb_compWarnMeaningless( pSelf ); break; case HB_EA_DELETE: - HB_XFREE( pSelf->value.asString ); + if( pSelf->value.asString.dealloc ) + HB_XFREE( pSelf->value.asString.string ); break; } return pSelf; diff --git a/harbour/include/hbexprc.c b/harbour/include/hbexprc.c index cc903c3dc2..f7ea60d1fd 100644 --- a/harbour/include/hbexprc.c +++ b/harbour/include/hbexprc.c @@ -448,3 +448,40 @@ BOOL hb_compExprCheckMacroVar( char * szText ) return bTextSubst; } +/* Reduces the list of expressions + * + * pExpr is the first expression on the list + */ +HB_EXPR_PTR hb_compExprReducePlusStrings( HB_EXPR_PTR pLeft, HB_EXPR_PTR pRight, HB_MACRO_DECL ) +#if defined( HB_MACRO_SUPPORT ) +{ + pLeft->value.asString.string = (char *) hb_xrealloc( pLeft->value.asString.string, pLeft->ulLength + pRight->ulLength + 1 ); + pLeft->value.asString.dealloc = TRUE; + memcpy( pLeft->value.asString.string + pLeft->ulLength, + pRight->value.asString.string, pRight->ulLength ); + pLeft->ulLength += pRight->ulLength; + pLeft->value.asString.string[ pLeft->ulLength ] = '\0'; + hb_compExprFree( pRight, HB_MACRO_PARAM ); + + return pLeft; +} +#else +{ + /* NOTE: compiler uses the hash table for storing identifiers and literals + * Strings passed for reduction can be referenced by other expressions + * then we cannot resize them or deallocate + */ + char *szString; + + szString = (char *) hb_xgrab( pLeft->ulLength + pRight->ulLength + 1 ); + memcpy( szString, pLeft->value.asString.string, pLeft->ulLength ); + memcpy( szString + pLeft->ulLength, pRight->value.asString.string, pRight->ulLength ); + pLeft->ulLength += pRight->ulLength; + szString[ pLeft->ulLength ] = '\0'; + pLeft->value.asString.string = szString; + pLeft->value.asString.dealloc = TRUE; + hb_compExprFree( pRight, HB_MACRO_PARAM ); + + return pLeft; +} +#endif diff --git a/harbour/include/hbexprop.h b/harbour/include/hbexprop.h index 3bc2072c92..3515bd9fef 100644 --- a/harbour/include/hbexprop.h +++ b/harbour/include/hbexprop.h @@ -150,10 +150,14 @@ typedef struct HB_EXPR_ { union { - char *asString; /* literal strings */ char *asSymbol; /* variable name */ BOOL asLogical; /* logical value */ struct + { + char *string; /* literal strings */ + BOOL dealloc; /* automatic deallocate on expresion deletion */ + } asString; + struct { struct HB_EXPR_ *pMacro; /* macro variable */ char *szName; /* variable name */ @@ -336,6 +340,7 @@ void hb_compExprErrorType( HB_EXPR_PTR, HB_MACRO_DECL ); HB_EXPR_PTR hb_compExprListStrip( HB_EXPR_PTR, HB_MACRO_DECL ); BOOL hb_compExprCheckMacroVar( char * ); void hb_compExprCBVarDel( HB_CBVAR_PTR ); +HB_EXPR_PTR hb_compExprReducePlusStrings( HB_EXPR_PTR, HB_EXPR_PTR, HB_MACRO_DECL ); #ifdef HB_MACRO_SUPPORT diff --git a/harbour/source/common/expropt1.c b/harbour/source/common/expropt1.c index 5cb3d5afcb..65c8cdd4e4 100644 --- a/harbour/source/common/expropt1.c +++ b/harbour/source/common/expropt1.c @@ -187,20 +187,6 @@ HB_EXPR_PTR hb_compExprNewLong( long lValue ) return pExpr; } -HB_EXPR_PTR hb_compExprNewString( char *szValue ) -{ - HB_EXPR_PTR pExpr; - - HB_TRACE(HB_TR_DEBUG, ("hb_compExprNewString(%s)", szValue)); - - pExpr =hb_compExprNew( HB_ET_STRING ); - - pExpr->value.asString = szValue; - pExpr->ulLength = strlen( szValue ); - pExpr->ValType = HB_EV_STRING; - - return pExpr; -} HB_EXPR_PTR hb_compExprNewCodeBlock( void ) { diff --git a/harbour/source/common/expropt2.c b/harbour/source/common/expropt2.c index e3ed8346a9..df6978b6fc 100644 --- a/harbour/source/common/expropt2.c +++ b/harbour/source/common/expropt2.c @@ -429,13 +429,7 @@ HB_EXPR_PTR hb_compExprReducePlus( HB_EXPR_PTR pSelf, HB_MACRO_DECL ) } else { - pLeft->value.asString = (char *) hb_xrealloc( pLeft->value.asString, pLeft->ulLength + pRight->ulLength + 1 ); - memcpy( pLeft->value.asString + pLeft->ulLength, - pRight->value.asString, pRight->ulLength ); - pLeft->ulLength += pRight->ulLength; - pLeft->value.asString[ pLeft->ulLength ] = '\0'; - pSelf = pLeft; - hb_compExprFree( pRight, HB_MACRO_PARAM ); + pSelf = hb_compExprReducePlusStrings( pLeft, pRight, HB_MACRO_PARAM ); } } else @@ -461,8 +455,8 @@ HB_EXPR_PTR hb_compExprReduceIN( HB_EXPR_PTR pSelf, HB_MACRO_DECL ) if( pSelf->value.asOperator.pLeft->ulLength == 0 ) bResult = TRUE; else - bResult = ( hb_strAt( pSelf->value.asOperator.pLeft->value.asString, pSelf->value.asOperator.pLeft->ulLength, - pSelf->value.asOperator.pRight->value.asString, pSelf->value.asOperator.pRight->ulLength ) != 0 ); + bResult = ( hb_strAt( pSelf->value.asOperator.pLeft->value.asString.string, pSelf->value.asOperator.pLeft->ulLength, + pSelf->value.asOperator.pRight->value.asString.string, pSelf->value.asOperator.pRight->ulLength ) != 0 ); /* NOTE: * "" $ "XXX" = .T. @@ -846,7 +840,7 @@ HB_EXPR_PTR hb_compExprReduceEQ( HB_EXPR_PTR pSelf, HB_MACRO_DECL ) BOOL bResult = FALSE; if( pLeft->ulLength == pRight->ulLength ) - bResult = ( strcmp( pLeft->value.asString, pRight->value.asString ) == 0 ); + bResult = ( strcmp( pLeft->value.asString.string, pRight->value.asString.string ) == 0 ); hb_compExprFree( pSelf->value.asOperator.pLeft, HB_MACRO_PARAM ); hb_compExprFree( pSelf->value.asOperator.pRight, HB_MACRO_PARAM ); pSelf->ExprType = HB_ET_LOGICAL; diff --git a/harbour/source/common/hash.c b/harbour/source/common/hash.c index b91235b6be..90c2109361 100644 --- a/harbour/source/common/hash.c +++ b/harbour/source/common/hash.c @@ -95,7 +95,6 @@ void hb_hashTableKill( HB_HASH_TABLE_PTR pTable ) { HB_HASH_ITEM_PTR pItem; HB_HASH_ITEM_PTR pNext; - pItem = pTable->pItems[ ulSize ]; while( pItem ) { diff --git a/harbour/source/compiler/harbour.l b/harbour/source/compiler/harbour.l index be9be1c44f..73127c5d88 100644 --- a/harbour/source/compiler/harbour.l +++ b/harbour/source/compiler/harbour.l @@ -221,7 +221,7 @@ Separator {SpaceTab} BEGIN 0; yytext[--yyleng] = '\0'; - yylval.string = hb_strdup( yytext ); + yylval.string = hb_compIdentifierNew( yytext, TRUE ); return LITERAL; } @@ -232,7 +232,7 @@ Separator {SpaceTab} BEGIN 0; yytext[--yyleng] = '\0'; - yylval.string = hb_strdup( yytext ); + yylval.string = hb_compIdentifierNew( yytext, TRUE ); return LITERAL; } @@ -243,7 +243,7 @@ Separator {SpaceTab} BEGIN 0; yytext[--yyleng] = '\0'; - yylval.string = hb_strdup( yytext ); + yylval.string = hb_compIdentifierNew( yytext, TRUE ); return LITERAL; } diff --git a/harbour/source/compiler/hbident.c b/harbour/source/compiler/hbident.c index f71a13b238..b2b2b8d3f8 100644 --- a/harbour/source/compiler/hbident.c +++ b/harbour/source/compiler/hbident.c @@ -40,7 +40,7 @@ static HB_HASH_TABLE_PTR s_comp_Identifiers; /* table of identifiers for reuse */ -#define HB_IDENT_BUCKET 211 +#define HB_IDENT_TABLE_SIZE 373UL /* create a new identifier or return the existing one */ @@ -65,15 +65,15 @@ char * hb_compIdentifierNew( char * szName, BOOL bCopy ) /* returns a hash key */ HB_HASH_FUNC( hb_comp_IdentKey ) /* ULONG func (void *Value, void *Cargo) */ { - unsigned char ucSum = 0; + ULONG ulSum = 0; char *szName = ( char * )Value; while( *szName ) - ucSum += *szName++; + ulSum += *szName++; HB_SYMBOL_UNUSED( Cargo ); - return ucSum % HB_IDENT_BUCKET; + return ulSum % HB_IDENT_TABLE_SIZE; } /* deletes an identifier */ @@ -93,7 +93,7 @@ HB_HASH_FUNC( hb_comp_IdentComp ) /* initialize the hash table for identifiers */ void hb_compIdentifierOpen( ) { - s_comp_Identifiers = hb_hashTableCreate( HB_IDENT_BUCKET, hb_comp_IdentKey, + s_comp_Identifiers = hb_hashTableCreate( HB_IDENT_TABLE_SIZE, hb_comp_IdentKey, hb_comp_IdentDel, hb_comp_IdentComp ); } diff --git a/harbour/source/macro/macroa.c b/harbour/source/macro/macroa.c index 22bd19764e..02376f85f4 100644 --- a/harbour/source/macro/macroa.c +++ b/harbour/source/macro/macroa.c @@ -5,7 +5,7 @@ /* hbexpra.c is also included from ../compiler/expropta.c * However it produces a slighty different code if used in * macro compiler (there is an additional parameter passed to some functions) - * 0 - ignore this magic number - this is used to force compilation + * 1 - ignore this magic number - this is used to force compilation */ #define HB_MACRO_SUPPORT diff --git a/harbour/source/macro/macrob.c b/harbour/source/macro/macrob.c index 32bc1bd9a3..0c3b433c2c 100644 --- a/harbour/source/macro/macrob.c +++ b/harbour/source/macro/macrob.c @@ -5,7 +5,7 @@ /* hbexprb.c is also included from ../compiler/exproptb.c * However it produces a slighty different code if used in * macro compiler (there is an additional parameter passed to some functions) - * 0 - ignore this magic number - this is used to force compilation + * 1 - ignore this magic number - this is used to force compilation */ #define HB_MACRO_SUPPORT diff --git a/harbour/source/macro/macroc.c b/harbour/source/macro/macroc.c index 1c443292f9..63397a58ce 100644 --- a/harbour/source/macro/macroc.c +++ b/harbour/source/macro/macroc.c @@ -5,7 +5,7 @@ /* hbexprc.c is also included from ../compiler/exproptc.c * However it produces a slighty different code if used in * macro compiler (there is an additional parameter passed to some functions) - * 0 - ignore this magic number - this is used to force compilation + * 1 - ignore this magic number - this is used to force compilation */ #define HB_MACRO_SUPPORT