From 7a7a4856c9fbbb8857f5b3cad9702d19ef3efa88 Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Tue, 30 Dec 2008 10:59:43 +0000 Subject: [PATCH] 2008-12-30 12:02 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/include/hbcomp.h * harbour/include/hbcompdf.h * harbour/include/hbexprb.c * harbour/source/common/expropt2.c * harbour/source/compiler/hbmain.c * harbour/source/compiler/hbcomp.c * harbour/source/compiler/harbour.y * harbour/source/compiler/harbour.yyc ! fixed == => optimizations if or contains valid ¯o. Such expressions cannot be optimized if -kM compiler switch is not used, f.e.: M->V := "ABC" ? "[&V]" == "[ABC]" ! fixed $ => optimizations if or contains valid ¯o. Such expressions cannot be optimized if -kM compiler switch is not used, f.e.: M->V := "ABC" ? "[&V]" $ " [ABC] " % do not disable + => and - => optimization when or contains valid ¯o but -kM compiler switch is used. * harbour/include/hbexprb.c * cover ! ! => optimization by -ko compile time switch * harbour/doc/cmpopt.txt * updated compiler optimization description --- harbour/ChangeLog | 29 ++++ harbour/doc/cmpopt.txt | 62 +++++--- harbour/include/hbcomp.h | 1 + harbour/include/hbcompdf.h | 1 - harbour/include/hbexprb.c | 4 +- harbour/source/common/expropt2.c | 232 ++++++++++++++++------------ harbour/source/compiler/harbour.y | 11 +- harbour/source/compiler/harbour.yyc | 11 +- harbour/source/compiler/hbcomp.c | 1 - harbour/source/compiler/hbmain.c | 1 - 10 files changed, 223 insertions(+), 130 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index de9802b67f..6668092a02 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,35 @@ 2008-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org) */ +2008-12-30 12:02 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbcomp.h + * harbour/include/hbcompdf.h + * harbour/include/hbexprb.c + * harbour/source/common/expropt2.c + * harbour/source/compiler/hbmain.c + * harbour/source/compiler/hbcomp.c + * harbour/source/compiler/harbour.y + * harbour/source/compiler/harbour.yyc + ! fixed == => optimizations if + or contains valid ¯o. Such expressions + cannot be optimized if -kM compiler switch is not used, f.e.: + M->V := "ABC" + ? "[&V]" == "[ABC]" + ! fixed $ => optimizations if + or contains valid ¯o. Such expressions + cannot be optimized if -kM compiler switch is not used, f.e.: + M->V := "ABC" + ? "[&V]" $ " [ABC] " + % do not disable + => and + - => optimization when or + contains valid ¯o but -kM compiler switch is used. + + * harbour/include/hbexprb.c + * cover ! ! => optimization by -ko compile time switch + + * harbour/doc/cmpopt.txt + * updated compiler optimization description + 2008-12-29 20:23 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/contrib/hbct/disk.c ! fixed dirname() - thanks to Saulius diff --git a/harbour/doc/cmpopt.txt b/harbour/doc/cmpopt.txt index d926ee99d2..4a6f39bba4 100644 --- a/harbour/doc/cmpopt.txt +++ b/harbour/doc/cmpopt.txt @@ -62,7 +62,9 @@ arguments are well known and can be callculated at compile time: // In Clipper neither nor // can contain '&' character. Harbour checks // if concatenation can change existing valid - // macro expression + // macro name or ignore '&' when -kM compiler + // switch which disable macro substitution + // is used - => - => - => @@ -70,16 +72,30 @@ arguments are well known and can be callculated at compile time: // In Clipper neither nor // can contain '&' character. Harbour checks // if concatenation can change existing valid - // macro expression + // macro name or ignore '&' when -kM compiler + // switch which disable macro substitution + // is used * => / => // Clipper optimize only integers % => - $ => // Clipper wrongly calculates - // "" $ as .T. + $ => + // Clipper wrongly calculates + // "" $ as .T. + // In Clipper neither nor + // can contain '&' character. Harbour checks + // if after '&' is potentially valid macro + // name or ignore '&' when -kM compiler switch + // which disable macro substitution is used == => == => == => == => + // In Clipper neither nor + // can contain '&' character. Harbour checks + // if after '&' is potentially valid macro + // name or ignore '&' when -kM compiler switch + // which disable macro substitution is used + NIL == => == NIL => = => @@ -113,7 +129,7 @@ arguments are well known and can be callculated at compile time: IIF( .T., , ) => IIF( .F., , ) => - - optimizations disabled by -z compiler switch + - optimizations which can be disabled by -z compiler switch .T. .AND. => .AND. .T. => @@ -131,20 +147,22 @@ arguments are well known and can be callculated at compile time: ( ) => // it allows to optimize // expresions like: 1+(2) - - Harbour extension which may disable RT errors in wrong expressions: - .NOT. .NOT. => - - - => - + 0 => - 0 + => - + "" => - "" + => + - Harbour extensions which may disable RT errors in wrong expressions + or can change used operators using basic math rules. Enabled by -ko + compiler switch: + .NOT. .NOT. => + - - => + + 0 => + 0 + => + + "" => + "" + => - In cases when result is miningless Harbour compiler can skip code - for operation, i.e. for such line of .prg code: - ( ) - where result of operation is ignored Harbour reduces the code - to: - ( , ) + In cases when result is miningless Harbour compiler can skip code + for operation, i.e. for such line of .prg code: + ( ) + where result of operation is ignored Harbour reduces the code + to: + ( , ) In Clipper in some places optiomization is not enabled, f.e. Clipper does not optimize in expressions like: @@ -154,7 +172,8 @@ Unlike Clipper Harbour tries to optimize all expressions. If some code needs strict Clipper behavior then it can be forced by using -kc Harbour compiler switch. It disabled Harbour extensions and enables replicating some Clipper bugs like optimizing "" $ to .T. at -compile time when at runtime it's always .F. +compile time (at runtime and in macrocompiler it's always .F. in Clipper +and Harbour). Expressions fully optimized to constant values at compile time can be used to intialize static variables, f.e.: @@ -163,4 +182,7 @@ to intialize static variables, f.e.: Harbour has additional optimization phase which operates on generated PCODE. It can also reduce expressions, joins jumps, removes death or meaningless code which can appear after all other optimizations and were not optimized -by expression optimizer. +by expression optimizer. It can also optimize readonly local variables +keeping the QSelf() value. QSelf() is not real function call but very fast +single PCODE often used in OOP code. Harbour can replace local variables +keeping it by direct QSelf() usage. diff --git a/harbour/include/hbcomp.h b/harbour/include/hbcomp.h index ff103e010f..c12765c40c 100644 --- a/harbour/include/hbcomp.h +++ b/harbour/include/hbcomp.h @@ -396,6 +396,7 @@ extern const BYTE hb_comp_pcode_len[]; #define HB_SUPPORT_HARBOUR ( HB_COMP_ISSUPPORTED(HB_COMPFLAG_HARBOUR) ) #define HB_SUPPORT_ARRSTR ( HB_COMP_ISSUPPORTED(HB_COMPFLAG_ARRSTR) ) #define HB_SUPPORT_EXTOPT ( HB_COMP_ISSUPPORTED(HB_COMPFLAG_EXTOPT) ) +#define HB_SUPPORT_MACROTEXT ( HB_COMP_ISSUPPORTED(HB_COMPFLAG_MACROTEXT) ) #if defined( HB_MACRO_SUPPORT ) # define HB_MACRO_GENFLAGS HB_COMPFLAG_RT_MACRO diff --git a/harbour/include/hbcompdf.h b/harbour/include/hbcompdf.h index 61d2c67d70..60d2f7e354 100644 --- a/harbour/include/hbcompdf.h +++ b/harbour/include/hbcompdf.h @@ -698,7 +698,6 @@ typedef struct _HB_COMP BOOL fBuildInfo; /* print build info */ BOOL fLogo; /* print logo */ BOOL fSyntaxCheckOnly; /* syntax check only */ - BOOL fTextSubst; /* check if string variables are macros (&) which needs substitution */ BOOL fLongOptimize; /* optimize PCODEs generated for integers */ BOOL fAutoOpen; /* automatically compile DO...[WITH...] external modules (-m) */ BOOL fError; /* error appeared during compilation */ diff --git a/harbour/include/hbexprb.c b/harbour/include/hbexprb.c index 1da278eab9..94ef27e530 100644 --- a/harbour/include/hbexprb.c +++ b/harbour/include/hbexprb.c @@ -358,7 +358,7 @@ static HB_EXPR_FUNC( hb_compExprUseString ) HB_GEN_FUNC2( PushString, pSelf->value.asString.string, pSelf->ulLength + 1 ); #if ! defined( HB_MACRO_SUPPORT ) - if( HB_COMP_PARAM->fTextSubst && + if( HB_SUPPORT_MACROTEXT && hb_compIsValidMacroText( HB_COMP_PARAM, pSelf->value.asString.string, pSelf->ulLength ) ) @@ -3067,7 +3067,7 @@ static HB_EXPR_FUNC( hb_compExprUseNot ) HB_COMP_EXPR_DELETE( pSelf ); pSelf = pExpr; } - else if( pExpr->ExprType == HB_EO_NOT && HB_SUPPORT_HARBOUR ) + else if( pExpr->ExprType == HB_EO_NOT && HB_SUPPORT_EXTOPT ) { /* NOTE: This will not generate a runtime error if incompatible * data type is used diff --git a/harbour/source/common/expropt2.c b/harbour/source/common/expropt2.c index eabc7bec6b..f8b87e7c43 100644 --- a/harbour/source/common/expropt2.c +++ b/harbour/source/common/expropt2.c @@ -60,6 +60,23 @@ #include "hbcomp.h" #include "hbdate.h" +static BOOL hb_compExprHasMacro( const char * szText, ULONG ulLen, HB_COMP_DECL ) +{ + while( ulLen-- ) + { + if( *szText++ == '&' ) + { + if( ! HB_SUPPORT_HARBOUR || ( ulLen && ( *szText == '_' || + ( *szText >= 'A' && *szText <= 'Z' ) || + ( *szText >= 'a' && *szText <= 'z' ) ) ) ) + { + return TRUE; + } + } + } + return FALSE; +} + static HB_EXPR_PTR hb_compExprReducePlusStrings( HB_EXPR_PTR pLeft, HB_EXPR_PTR pRight, HB_COMP_DECL ) { if( pLeft->value.asString.dealloc ) @@ -496,26 +513,28 @@ HB_EXPR_PTR hb_compExprReduceMinus( HB_EXPR_PTR pSelf, HB_COMP_DECL ) } else { - /* Do not reduce strings with the macro operator '&' - */ - char * szText = pLeft->value.asString.string; - ULONG ulLen = pLeft->ulLength; BOOL fReduce = TRUE; - while( ulLen && szText[ ulLen - 1 ] == ' ' ) - --ulLen; - - while( ulLen-- ) + /* Do not reduce strings with the macro operator '&' + */ + if( HB_SUPPORT_MACROTEXT ) { - if( *szText++ == '&' ) + char * szText = pLeft->value.asString.string; + ULONG ulLen = pLeft->ulLength; + while( ulLen && szText[ ulLen - 1 ] == ' ' ) + --ulLen; + while( ulLen-- ) { - char ch = ulLen ? *szText : *pRight->value.asString.string; - if( ( ch >= 'A' && ch <= 'Z' ) || - ( ch >= 'a' && ch <= 'z' ) || ch == '_' || - ! HB_SUPPORT_HARBOUR ) + if( *szText++ == '&' ) { - fReduce = FALSE; - break; + char ch = ulLen ? *szText : *pRight->value.asString.string; + if( ( ch >= 'A' && ch <= 'Z' ) || + ( ch >= 'a' && ch <= 'z' ) || ch == '_' || + ! HB_SUPPORT_HARBOUR ) + { + fReduce = FALSE; + break; + } } } } @@ -757,27 +776,30 @@ HB_EXPR_PTR hb_compExprReducePlus( HB_EXPR_PTR pSelf, HB_COMP_DECL ) } else { - /* Do not reduce strings with the macro operator '&' - */ - char * szText = pLeft->value.asString.string; - ULONG ulLen = pLeft->ulLength; BOOL fReduce = TRUE; - while( ulLen-- ) + /* Do not reduce strings with the macro operator '&' + */ + if( HB_SUPPORT_MACROTEXT ) { - if( *szText++ == '&' ) + char * szText = pLeft->value.asString.string; + ULONG ulLen = pLeft->ulLength; + + while( ulLen-- ) { - char ch = ulLen ? *szText : *pRight->value.asString.string; - if( ( ch >= 'A' && ch <= 'Z' ) || - ( ch >= 'a' && ch <= 'z' ) || ch == '_' || - ! HB_SUPPORT_HARBOUR ) + if( *szText++ == '&' ) { - fReduce = FALSE; - break; + char ch = ulLen ? *szText : *pRight->value.asString.string; + if( ( ch >= 'A' && ch <= 'Z' ) || + ( ch >= 'a' && ch <= 'z' ) || ch == '_' || + ! HB_SUPPORT_HARBOUR ) + { + fReduce = FALSE; + break; + } } } } - if( fReduce ) { pSelf->ExprType = HB_ET_NONE; /* suppress deletion of operator components */ @@ -844,38 +866,50 @@ HB_EXPR_PTR hb_compExprReduceNegate( HB_EXPR_PTR pSelf, HB_COMP_DECL ) HB_EXPR_PTR hb_compExprReduceIN( HB_EXPR_PTR pSelf, HB_COMP_DECL ) { - if( pSelf->value.asOperator.pLeft->ExprType == pSelf->value.asOperator.pRight->ExprType && - pSelf->value.asOperator.pLeft->ExprType == HB_ET_STRING ) + HB_EXPR_PTR pLeft, pRight; + + pLeft = pSelf->value.asOperator.pLeft; + pRight = pSelf->value.asOperator.pRight; + + if( pLeft->ExprType == pRight->ExprType && pLeft->ExprType == HB_ET_STRING ) { /* Both arguments are literal strings */ - BOOL bResult; - /* NOTE: CA-Cl*pper has a bug where the $ operator returns .T. - * when an empty string is searched [vszakats] - * - * But this bug exist only in compiler and CA-Cl*pper macro - * compiler does not have optimizer. This bug is replicated - * by us only when Harbour extensions in compiler (-kh) are - * not enabled f.e. in strict Clipper cmpatible mode (-kc) - * [druzus] + /* NOTE: If macro substitiution is not didabled (-kM compiler + * switch) then we cannot reduce also strings which + * have macro operator '&' */ - if( pSelf->value.asOperator.pLeft->ulLength == 0 ) - bResult = HB_COMP_PARAM->mode == HB_MODE_COMPILER && - ! HB_SUPPORT_HARBOUR; - else - 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 ); + if( !HB_SUPPORT_MACROTEXT || + ( !hb_compExprHasMacro( pLeft->value.asString.string, + pLeft->ulLength, HB_COMP_PARAM ) && + !hb_compExprHasMacro( pRight->value.asString.string, + pRight->ulLength, HB_COMP_PARAM ) ) ) + { + BOOL bResult; - /* NOTE: - * "" $ "XXX" = .T. - * "" $ "" = .T. - */ - HB_COMP_EXPR_FREE( pSelf->value.asOperator.pLeft ); - HB_COMP_EXPR_FREE( pSelf->value.asOperator.pRight ); - pSelf->ExprType = HB_ET_LOGICAL; - pSelf->ValType = HB_EV_LOGICAL; - pSelf->value.asLogical = bResult; + /* NOTE: CA-Cl*pper has a bug where the $ operator returns .T. + * when an empty string is searched [vszakats] + * + * But this bug exist only in compiler and CA-Cl*pper macro + * compiler does not have optimizer. This bug is replicated + * by us only when Harbour extensions in compiler (-kh) are + * not enabled f.e. in strict Clipper cmpatible mode (-kc) + * [druzus] + */ + if( pLeft->ulLength == 0 ) + bResult = HB_COMP_PARAM->mode == HB_MODE_COMPILER && + ! HB_SUPPORT_HARBOUR; + else + bResult = ( hb_strAt( pLeft->value.asString.string, pLeft->ulLength, + pRight->value.asString.string, pRight->ulLength ) != 0 ); + + HB_COMP_EXPR_FREE( pLeft ); + HB_COMP_EXPR_FREE( pRight ); + pSelf->ExprType = HB_ET_LOGICAL; + pSelf->ValType = HB_EV_LOGICAL; + pSelf->value.asLogical = bResult; + } } /* TODO: add checking for incompatible types */ @@ -1321,25 +1355,33 @@ HB_EXPR_PTR hb_compExprReduceEQ( HB_EXPR_PTR pSelf, HB_COMP_DECL ) switch( pLeft->ExprType ) { case HB_ET_LOGICAL: - { - BOOL bResult = ( pLeft->value.asLogical == pRight->value.asLogical ); - HB_COMP_EXPR_FREE( pLeft ); - HB_COMP_EXPR_FREE( pRight ); - pSelf->ExprType = HB_ET_LOGICAL; - pSelf->ValType = HB_EV_LOGICAL; - pSelf->value.asLogical = bResult; - } + { + BOOL bResult = ( pLeft->value.asLogical == pRight->value.asLogical ); + HB_COMP_EXPR_FREE( pLeft ); + HB_COMP_EXPR_FREE( pRight ); + pSelf->ExprType = HB_ET_LOGICAL; + pSelf->ValType = HB_EV_LOGICAL; + pSelf->value.asLogical = bResult; break; + } case HB_ET_STRING: /* NOTE: when not exact comparison (==) is used * the result depends on SET EXACT setting then it * cannot be optimized except the case when NULL string are * compared - "" = "" is always TRUE regardless of EXACT - * setting + * setting. + * If macro substitiution is not didabled (-kM compiler + * switch) then we cannot reduce also strings which + * have macro operator '&' */ - if( pSelf->ExprType == HB_EO_EQ || - ( pLeft->ulLength | pRight->ulLength ) == 0 ) + if( ( pLeft->ulLength | pRight->ulLength ) == 0 || + ( pSelf->ExprType == HB_EO_EQ && + ( !HB_SUPPORT_MACROTEXT || + ( !hb_compExprHasMacro( pLeft->value.asString.string, + pLeft->ulLength, HB_COMP_PARAM ) && + !hb_compExprHasMacro( pRight->value.asString.string, + pRight->ulLength, HB_COMP_PARAM ) ) ) ) ) { BOOL bResult = pLeft->ulLength == pRight->ulLength && memcmp( pLeft->value.asString.string, @@ -1354,42 +1396,42 @@ HB_EXPR_PTR hb_compExprReduceEQ( HB_EXPR_PTR pSelf, HB_COMP_DECL ) break; case HB_ET_NUMERIC: - { - BOOL bResult; + { + BOOL bResult; - switch( pLeft->value.asNum.NumType & pRight->value.asNum.NumType ) - { - case HB_ET_LONG: - bResult = ( pLeft->value.asNum.val.l == pRight->value.asNum.val.l ); - break; - case HB_ET_DOUBLE: - bResult = ( pLeft->value.asNum.val.d == pRight->value.asNum.val.d ); - break; - default: - if( pLeft->value.asNum.NumType == HB_ET_LONG ) - bResult = ( pLeft->value.asNum.val.l == pRight->value.asNum.val.d ); - else - bResult = ( pLeft->value.asNum.val.d == pRight->value.asNum.val.l ); - break; - } - HB_COMP_EXPR_FREE( pLeft ); - HB_COMP_EXPR_FREE( pRight ); - pSelf->ExprType = HB_ET_LOGICAL; - pSelf->ValType = HB_EV_LOGICAL; - pSelf->value.asLogical = bResult; + switch( pLeft->value.asNum.NumType & pRight->value.asNum.NumType ) + { + case HB_ET_LONG: + bResult = ( pLeft->value.asNum.val.l == pRight->value.asNum.val.l ); + break; + case HB_ET_DOUBLE: + bResult = ( pLeft->value.asNum.val.d == pRight->value.asNum.val.d ); + break; + default: + if( pLeft->value.asNum.NumType == HB_ET_LONG ) + bResult = ( pLeft->value.asNum.val.l == pRight->value.asNum.val.d ); + else + bResult = ( pLeft->value.asNum.val.d == pRight->value.asNum.val.l ); + break; } + HB_COMP_EXPR_FREE( pLeft ); + HB_COMP_EXPR_FREE( pRight ); + pSelf->ExprType = HB_ET_LOGICAL; + pSelf->ValType = HB_EV_LOGICAL; + pSelf->value.asLogical = bResult; break; + } case HB_ET_DATE: - { - BOOL bResult = pLeft->value.asNum.val.l == pRight->value.asNum.val.l; - HB_COMP_EXPR_FREE( pLeft ); - HB_COMP_EXPR_FREE( pRight ); - pSelf->ExprType = HB_ET_LOGICAL; - pSelf->ValType = HB_EV_LOGICAL; - pSelf->value.asLogical = bResult; - } + { + BOOL bResult = pLeft->value.asNum.val.l == pRight->value.asNum.val.l; + HB_COMP_EXPR_FREE( pLeft ); + HB_COMP_EXPR_FREE( pRight ); + pSelf->ExprType = HB_ET_LOGICAL; + pSelf->ValType = HB_EV_LOGICAL; + pSelf->value.asLogical = bResult; break; + } case HB_ET_NIL: HB_COMP_EXPR_FREE( pLeft ); diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 29b81eec3e..14a13876b8 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -2642,7 +2642,7 @@ static void hb_compSwitchAdd( HB_COMP_DECL, HB_EXPR_PTR pExpr ) static void hb_compSwitchEnd( HB_COMP_DECL ) { BOOL fLongOptimize = HB_COMP_PARAM->fLongOptimize; - BOOL fTextSubst = HB_COMP_PARAM->fTextSubst; + BOOL fMacroText = ( HB_COMP_PARAM->supported & HB_COMPFLAG_MACROTEXT ) != 0; PFUNCTION pFunc = HB_COMP_PARAM->functions.pLast; HB_SWITCHCASE_PTR pCase = pFunc->pSwitch->pCases; HB_SWITCHCASE_PTR pTmp; @@ -2652,12 +2652,12 @@ static void hb_compSwitchEnd( HB_COMP_DECL ) /* skip switch pcode if there was no EXIT in the last CASE * or in the DEFAULT case */ - ulExitPos = hb_compGenJump( 0, HB_COMP_PARAM ); + ulExitPos = hb_compGenJump( 0, HB_COMP_PARAM ); hb_compGenJumpHere( pFunc->pSwitch->ulOffset + 1, HB_COMP_PARAM ); hb_compGenPCode3( HB_P_SWITCH, HB_LOBYTE( pFunc->pSwitch->iCount ), HB_HIBYTE( pFunc->pSwitch->iCount ), HB_COMP_PARAM ); - HB_COMP_PARAM->fLongOptimize = FALSE; - HB_COMP_PARAM->fTextSubst = FALSE; + HB_COMP_PARAM->fLongOptimize = FALSE; + HB_COMP_PARAM->supported &= ~HB_COMPFLAG_MACROTEXT; while( pCase ) { if( pCase->pExpr ) @@ -2683,7 +2683,8 @@ static void hb_compSwitchEnd( HB_COMP_DECL ) } HB_COMP_PARAM->fLongOptimize = fLongOptimize; - HB_COMP_PARAM->fTextSubst = fTextSubst; + if( fMacroText ) + HB_COMP_PARAM->supported |= HB_COMPFLAG_MACROTEXT; hb_compGenJumpHere( ulExitPos, HB_COMP_PARAM ); diff --git a/harbour/source/compiler/harbour.yyc b/harbour/source/compiler/harbour.yyc index 071ca9a83d..9352f1c918 100644 --- a/harbour/source/compiler/harbour.yyc +++ b/harbour/source/compiler/harbour.yyc @@ -8005,7 +8005,7 @@ static void hb_compSwitchAdd( HB_COMP_DECL, HB_EXPR_PTR pExpr ) static void hb_compSwitchEnd( HB_COMP_DECL ) { BOOL fLongOptimize = HB_COMP_PARAM->fLongOptimize; - BOOL fTextSubst = HB_COMP_PARAM->fTextSubst; + BOOL fMacroText = ( HB_COMP_PARAM->supported & HB_COMPFLAG_MACROTEXT ) != 0; PFUNCTION pFunc = HB_COMP_PARAM->functions.pLast; HB_SWITCHCASE_PTR pCase = pFunc->pSwitch->pCases; HB_SWITCHCASE_PTR pTmp; @@ -8015,12 +8015,12 @@ static void hb_compSwitchEnd( HB_COMP_DECL ) /* skip switch pcode if there was no EXIT in the last CASE * or in the DEFAULT case */ - ulExitPos = hb_compGenJump( 0, HB_COMP_PARAM ); + ulExitPos = hb_compGenJump( 0, HB_COMP_PARAM ); hb_compGenJumpHere( pFunc->pSwitch->ulOffset + 1, HB_COMP_PARAM ); hb_compGenPCode3( HB_P_SWITCH, HB_LOBYTE( pFunc->pSwitch->iCount ), HB_HIBYTE( pFunc->pSwitch->iCount ), HB_COMP_PARAM ); - HB_COMP_PARAM->fLongOptimize = FALSE; - HB_COMP_PARAM->fTextSubst = FALSE; + HB_COMP_PARAM->fLongOptimize = FALSE; + HB_COMP_PARAM->supported &= ~HB_COMPFLAG_MACROTEXT; while( pCase ) { if( pCase->pExpr ) @@ -8046,7 +8046,8 @@ static void hb_compSwitchEnd( HB_COMP_DECL ) } HB_COMP_PARAM->fLongOptimize = fLongOptimize; - HB_COMP_PARAM->fTextSubst = fTextSubst; + if( fMacroText ) + HB_COMP_PARAM->supported |= HB_COMPFLAG_MACROTEXT; hb_compGenJumpHere( ulExitPos, HB_COMP_PARAM ); diff --git a/harbour/source/compiler/hbcomp.c b/harbour/source/compiler/hbcomp.c index 02ac2f04e7..c6407f393c 100644 --- a/harbour/source/compiler/hbcomp.c +++ b/harbour/source/compiler/hbcomp.c @@ -218,7 +218,6 @@ HB_COMP_PTR hb_comp_new( void ) HB_COMPFLAG_MACROTEXT | HB_COMPFLAG_SHORTCUTS; - pComp->fTextSubst = ( pComp->supported & HB_COMPFLAG_MACROTEXT ) != 0; pComp->fLongOptimize = TRUE; pComp->fPPO = FALSE; /* flag indicating, is ppo output needed */ pComp->fStartProc = TRUE; /* holds if we need to create the starting procedure */ diff --git a/harbour/source/compiler/hbmain.c b/harbour/source/compiler/hbmain.c index af240fdb7f..f7243718cf 100644 --- a/harbour/source/compiler/hbmain.c +++ b/harbour/source/compiler/hbmain.c @@ -3652,7 +3652,6 @@ static void hb_compInitVars( HB_COMP_DECL ) HB_COMP_PARAM->funcalls.pFirst = NULL; HB_COMP_PARAM->funcalls.pLast = NULL; HB_COMP_PARAM->szAnnounce = NULL; - HB_COMP_PARAM->fTextSubst = ( HB_COMP_PARAM->supported & HB_COMPFLAG_MACROTEXT ) != 0; HB_COMP_PARAM->fLongOptimize = TRUE; HB_COMP_PARAM->symbols.iCount = 0;