From d4f903942a25a1fad1671fb6b8d7bf0e9dea96bc Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Sun, 7 Oct 2012 12:41:26 +0000 Subject: [PATCH] 2012-10-07 14:40 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * harbour/include/hbcomp.h * harbour/src/compiler/hbmain.c * harbour/src/compiler/hbstripl.c % eliminate repeated HB_P_LINE pcodes bound by unconditional jump This optimization is not enabled when debug mode (-b) is used. * harbour/include/hberrors.h * harbour/src/compiler/hbgenerr.c * harbour/src/compiler/harbour.y * harbour/src/compiler/harbour.yyc + added new compile time error: "Duplicate case value" --- harbour/ChangeLog | 13 +++++++++++++ harbour/include/hbcomp.h | 2 +- harbour/include/hberrors.h | 9 +++++---- harbour/src/compiler/harbour.y | 28 ++++++++++++++++++++++++++-- harbour/src/compiler/harbour.yyc | 28 ++++++++++++++++++++++++++-- harbour/src/compiler/hbgenerr.c | 1 + harbour/src/compiler/hbmain.c | 4 ++-- harbour/src/compiler/hbstripl.c | 25 ++++++++++++++++++++++--- 8 files changed, 96 insertions(+), 14 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 7f84a83744..06fae8d980 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,19 @@ The license applies to all entries newer than 2009-04-28. */ +2012-10-07 14:40 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * harbour/include/hbcomp.h + * harbour/src/compiler/hbmain.c + * harbour/src/compiler/hbstripl.c + % eliminate repeated HB_P_LINE pcodes bound by unconditional jump + This optimization is not enabled when debug mode (-b) is used. + + * harbour/include/hberrors.h + * harbour/src/compiler/hbgenerr.c + * harbour/src/compiler/harbour.y + * harbour/src/compiler/harbour.yyc + + added new compile time error: "Duplicate case value" + 2012-10-06 17:20 UTC+0200 Viktor Szakats (harbour syenar.net) * src/rtl/checkbox.prg ! another very old visual bug on the appearance of non-checked diff --git a/harbour/include/hbcomp.h b/harbour/include/hbcomp.h index b5f8b8a339..c1f4d6d228 100644 --- a/harbour/include/hbcomp.h +++ b/harbour/include/hbcomp.h @@ -324,7 +324,7 @@ extern void hb_compCodeTraceMarkDead( HB_COMP_DECL, PFUNCTION pFunc ); extern void hb_compOptimizePCode( HB_COMP_DECL, PFUNCTION pFunc ); extern void hb_compPCodeTraceOptimizer( HB_COMP_DECL ); /* Misc functions defined in hbstripl.c */ -extern void hb_compStripFuncLines( PFUNCTION pFunc ); +extern void hb_compStripFuncLines( HB_COMP_DECL, PFUNCTION pFunc ); /* output related functions defined in gen*.c */ extern void hb_compGenCCode( HB_COMP_DECL, PHB_FNAME ); /* generates the C language output */ diff --git a/harbour/include/hberrors.h b/harbour/include/hberrors.h index 8bb4236489..fd91bbe98b 100644 --- a/harbour/include/hberrors.h +++ b/harbour/include/hberrors.h @@ -129,10 +129,11 @@ HB_EXTERN_BEGIN #define HB_COMP_ERR_OPEN_CFG 67 #define HB_COMP_ERR_ALWAYS_AFTER_EXIT 68 #define HB_COMP_ERR_FILE_WRITE 69 -#define HB_COMP_ERR_HISTORICAL_1 70 -#define HB_COMP_ERR_HISTORICAL_2 71 -#define HB_COMP_ERR_HISTORICAL_3 72 -#define HB_COMP_ERR_HISTORICAL_4 73 +#define HB_COMP_ERR_DUPL_CASE 70 +#define HB_COMP_ERR_HISTORICAL_1 71 +#define HB_COMP_ERR_HISTORICAL_2 72 +#define HB_COMP_ERR_HISTORICAL_3 73 +#define HB_COMP_ERR_HISTORICAL_4 74 #define HB_COMP_WARN_AMBIGUOUS_VAR 1 #define HB_COMP_WARN_MEMVAR_ASSUMED 2 diff --git a/harbour/src/compiler/harbour.y b/harbour/src/compiler/harbour.y index bc92e935bd..ad6e8c5b99 100644 --- a/harbour/src/compiler/harbour.y +++ b/harbour/src/compiler/harbour.y @@ -2584,11 +2584,35 @@ static void hb_compSwitchAdd( HB_COMP_DECL, HB_EXPR_PTR pExpr ) pCase = (HB_SWITCHCASE_PTR) hb_xgrab( sizeof( HB_SWITCHCASE ) ); pCase->nOffset = pFunc->nPCodePos; pCase->pNext = NULL; - pExpr = hb_compExprReduce( pExpr, HB_COMP_PARAM ); + pCase->pExpr = pExpr = hb_compExprReduce( pExpr, HB_COMP_PARAM ); if( !( hb_compExprIsLong( pExpr ) || hb_compExprIsString( pExpr ) ) ) hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_NOT_LITERAL_CASE, NULL, NULL ); + else if( pFunc->pSwitch->pCases ) + { + HB_SWITCHCASE_PTR pCases = pFunc->pSwitch->pCases; + while( pCases ) + { + HB_BOOL fEqual = HB_FALSE; + + if( hb_compExprIsLong( pExpr ) ) + { + if( hb_compExprIsLong( pCases->pExpr ) ) + fEqual = hb_compExprAsLongNum( pExpr ) == hb_compExprAsLongNum( pCases->pExpr ); + } + else + { + if( hb_compExprIsString( pCases->pExpr ) ) + fEqual = hb_compExprAsStringLen( pExpr ) == hb_compExprAsStringLen( pCases->pExpr ) && + memcmp( hb_compExprAsString( pExpr ), + hb_compExprAsString( pCases->pExpr ), + hb_compExprAsStringLen( pExpr ) ) == 0; + } + if( fEqual ) + hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_DUPL_CASE, NULL, NULL ); + pCases = pCases->pNext; + } + } - pCase->pExpr = pExpr; if( pFunc->pSwitch->pLast ) { diff --git a/harbour/src/compiler/harbour.yyc b/harbour/src/compiler/harbour.yyc index 98eecf0154..110cfb2bcb 100644 --- a/harbour/src/compiler/harbour.yyc +++ b/harbour/src/compiler/harbour.yyc @@ -8487,11 +8487,35 @@ static void hb_compSwitchAdd( HB_COMP_DECL, HB_EXPR_PTR pExpr ) pCase = (HB_SWITCHCASE_PTR) hb_xgrab( sizeof( HB_SWITCHCASE ) ); pCase->nOffset = pFunc->nPCodePos; pCase->pNext = NULL; - pExpr = hb_compExprReduce( pExpr, HB_COMP_PARAM ); + pCase->pExpr = pExpr = hb_compExprReduce( pExpr, HB_COMP_PARAM ); if( !( hb_compExprIsLong( pExpr ) || hb_compExprIsString( pExpr ) ) ) hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_NOT_LITERAL_CASE, NULL, NULL ); + else if( pFunc->pSwitch->pCases ) + { + HB_SWITCHCASE_PTR pCases = pFunc->pSwitch->pCases; + while( pCases ) + { + HB_BOOL fEqual = HB_FALSE; + + if( hb_compExprIsLong( pExpr ) ) + { + if( hb_compExprIsLong( pCases->pExpr ) ) + fEqual = hb_compExprAsLongNum( pExpr ) == hb_compExprAsLongNum( pCases->pExpr ); + } + else + { + if( hb_compExprIsString( pCases->pExpr ) ) + fEqual = hb_compExprAsStringLen( pExpr ) == hb_compExprAsStringLen( pCases->pExpr ) && + memcmp( hb_compExprAsString( pExpr ), + hb_compExprAsString( pCases->pExpr ), + hb_compExprAsStringLen( pExpr ) ) == 0; + } + if( fEqual ) + hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_DUPL_CASE, NULL, NULL ); + pCases = pCases->pNext; + } + } - pCase->pExpr = pExpr; if( pFunc->pSwitch->pLast ) { diff --git a/harbour/src/compiler/hbgenerr.c b/harbour/src/compiler/hbgenerr.c index ca4830624a..eebd441d1b 100644 --- a/harbour/src/compiler/hbgenerr.c +++ b/harbour/src/compiler/hbgenerr.c @@ -100,6 +100,7 @@ const char * const hb_comp_szErrors[] = "Can't find %s file", "Invalid ALWAYS after %s in RECOVER code", "File write error", + "Duplicate case value", /* Some historical, funny sounding error messages from original CA-Cl*pper. They serve no purpose whatsoever. [vszakats] */ "END wreaks terrible vengeance on control stack", diff --git a/harbour/src/compiler/hbmain.c b/harbour/src/compiler/hbmain.c index b0382cc451..f7c1ba8456 100644 --- a/harbour/src/compiler/hbmain.c +++ b/harbour/src/compiler/hbmain.c @@ -1346,7 +1346,7 @@ static void hb_compOptimizeJumps( HB_COMP_DECL ) if( iPass == 3 && fLineStrip ) { - hb_compStripFuncLines( HB_COMP_PARAM->functions.pLast ); + hb_compStripFuncLines( HB_COMP_PARAM, HB_COMP_PARAM->functions.pLast ); fLineStrip = HB_FALSE; } @@ -1501,7 +1501,7 @@ static void hb_compOptimizeJumps( HB_COMP_DECL ) if( iPass == 0 ) continue; if( fLineStrip ) - hb_compStripFuncLines( HB_COMP_PARAM->functions.pLast ); + hb_compStripFuncLines( HB_COMP_PARAM, HB_COMP_PARAM->functions.pLast ); if( HB_COMP_PARAM->functions.pLast->nNOOPs == 0 ) return; } diff --git a/harbour/src/compiler/hbstripl.c b/harbour/src/compiler/hbstripl.c index 70fe24ae58..2f0885bd37 100644 --- a/harbour/src/compiler/hbstripl.c +++ b/harbour/src/compiler/hbstripl.c @@ -66,12 +66,31 @@ HB_EXTERN_END static HB_STRIP_FUNC( hb_p_line ) { - HB_SYMBOL_UNUSED( cargo ); switch( pFunc->pCode[ nPCodePos + 3 ] ) { case HB_P_LINE: case HB_P_MODULENAME: hb_compNOOPfill( pFunc, nPCodePos, 3, HB_FALSE, HB_FALSE ); + break; + default: + if( !( ( HB_COMP_PTR ) cargo )->fDebugInfo ) + { + HB_SIZE nNewPos = nPCodePos; + switch( pFunc->pCode[ nPCodePos + 3 ] ) + { + case HB_P_JUMPNEAR: + nNewPos += 3 + ( signed char ) pFunc->pCode[ nPCodePos + 4 ]; + break; + case HB_P_JUMP: + nNewPos += 3 + HB_PCODE_MKSHORT( &pFunc->pCode[ nPCodePos + 4 ] ); + break; + case HB_P_JUMPFAR: + nNewPos += 3 + HB_PCODE_MKINT24( &pFunc->pCode[ nPCodePos + 4 ] ); + break; + } + if( nNewPos != nPCodePos && pFunc->pCode[ nNewPos ] == HB_P_LINE ) + hb_compNOOPfill( pFunc, nPCodePos, 3, HB_FALSE, HB_FALSE ); + } } return 3; @@ -268,9 +287,9 @@ static const PHB_STRIP_FUNC s_stripLines_table[] = NULL /* HB_P_PUSHAPARAMS */ }; -void hb_compStripFuncLines( PFUNCTION pFunc ) +void hb_compStripFuncLines( HB_COMP_DECL, PFUNCTION pFunc ) { assert( HB_P_LAST_PCODE == sizeof( s_stripLines_table ) / sizeof( PHB_STRIP_FUNC ) ); - hb_compPCodeEval( pFunc, s_stripLines_table, NULL ); + hb_compPCodeEval( pFunc, s_stripLines_table, ( void * ) HB_COMP_PARAM ); }