From ed6250363e9e8a644bc95f0453d27bb5500f8040 Mon Sep 17 00:00:00 2001 From: Mindaugas Kavaliauskas Date: Fri, 19 Apr 2013 16:56:30 +0300 Subject: [PATCH] 2013-04-19 16:55 UTC+0300 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt) * harbour/contrib/rddads/adsx.c ! fixed adsSeek() if seek string length is less than index key length * harbour/src/compiler/hbopt.c ! improved BEGIN/END SEQUENCE support in code trace optimizer. Problem of false positive warning 'Variable is assigned but not used' is solved in cases like: FUNC TEST() LOCAL n := 1 BEGIN SEQUENCE IF n == 1 n := 2 BREAK ENDIF n := 3 END SEQUENCE RETURN n ; TODO: test for more complicated cases like nested BEGIN/END SEQUENCE * harbour/src/rdd/dbf1.c * added :GetValue() GPF protection if area is "half opened" (ex., enumerating field values in error handler on area open failure). More general solution for "half opened" workareas is welcome --- ChangeLog.txt | 25 ++++++++++++++ contrib/rddads/adsx.c | 36 +++++++++++++------ src/compiler/hbopt.c | 80 +++++++++++++++++++++++++++---------------- src/rdd/dbf1.c | 2 +- 4 files changed, 102 insertions(+), 41 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 259a90eba9..c45614cac9 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,31 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2013-04-19 16:55 UTC+0300 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt) + * harbour/contrib/rddads/adsx.c + ! fixed adsSeek() if seek string length is less than index key length + + * harbour/src/compiler/hbopt.c + ! improved BEGIN/END SEQUENCE support in code trace optimizer. Problem + of false positive warning 'Variable is assigned but not used' is solved + in cases like: + FUNC TEST() + LOCAL n := 1 + BEGIN SEQUENCE + IF n == 1 + n := 2 + BREAK + ENDIF + n := 3 + END SEQUENCE + RETURN n + ; TODO: test for more complicated cases like nested BEGIN/END SEQUENCE + + * harbour/src/rdd/dbf1.c + * added :GetValue() GPF protection if area is "half opened" (ex., + enumerating field values in error handler on area open failure). + More general solution for "half opened" workareas is welcome + 2013-04-19 16:35 UTC+0300 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt) * contrib/hbct/token1.c * contrib/hbpgsql/rddcopy.c diff --git a/contrib/rddads/adsx.c b/contrib/rddads/adsx.c index d1b5d428b0..2ed9491048 100644 --- a/contrib/rddads/adsx.c +++ b/contrib/rddads/adsx.c @@ -341,7 +341,7 @@ static void mixQSort( PMIXKEY * pKeys, HB_ULONG left, HB_ULONG right, HB_USHORT } -static PMIXKEY mixFindKey( PMIXTAG pTag, PMIXKEY pKey, HB_ULONG * ulKeyPos ) +static PMIXKEY mixFindKeyLen( PMIXTAG pTag, PMIXKEY pKey, HB_USHORT uiLen, HB_ULONG * ulKeyPos ) { HB_ULONG l, r; int i = 1; @@ -358,7 +358,7 @@ static PMIXKEY mixFindKey( PMIXTAG pTag, PMIXKEY pKey, HB_ULONG * ulKeyPos ) while( l < r ) { - i = mixQSortCompare( pTag->pKeys[ ( l + r ) / 2 ], pKey, pTag->uiLen, pTag->pCodepage ); + i = mixQSortCompare( pTag->pKeys[ ( l + r ) / 2 ], pKey, uiLen, pTag->pCodepage ); if( i < 0 ) l = ( l + r ) / 2 + 1; @@ -370,7 +370,7 @@ static PMIXKEY mixFindKey( PMIXTAG pTag, PMIXKEY pKey, HB_ULONG * ulKeyPos ) if( i ) { - i = mixQSortCompare( pTag->pKeys[ l ], pKey, pTag->uiLen, pTag->pCodepage ); + i = mixQSortCompare( pTag->pKeys[ l ], pKey, uiLen, pTag->pCodepage ); if( i < 0 ) l++; } @@ -382,9 +382,15 @@ static PMIXKEY mixFindKey( PMIXTAG pTag, PMIXKEY pKey, HB_ULONG * ulKeyPos ) } -static int mixCompareKey( PMIXTAG pTag, HB_ULONG ulKeyPos, PMIXKEY pKey ) +static PMIXKEY mixFindKey( PMIXTAG pTag, PMIXKEY pKey, HB_ULONG * ulKeyPos ) { - return mixQSortCompare( pTag->pKeys[ ulKeyPos ], pKey, pTag->uiLen, pTag->pCodepage ); + return mixFindKeyLen( pTag, pKey, pTag->uiLen, ulKeyPos ); +} + + +static int mixCompareKey( PMIXTAG pTag, HB_ULONG ulKeyPos, PMIXKEY pKey, HB_USHORT uiLen ) +{ + return mixQSortCompare( pTag->pKeys[ ulKeyPos ], pKey, uiLen, pTag->pCodepage ); } @@ -661,7 +667,7 @@ static void mixUpdateDestroy( ADSXAREAP pArea, PMIXUPDATE pUpdate, int fUpdate ) PMIXKEY pKey = mixKeyEval( pTag, pArea ); if( bFor ) { - if( mixCompareKey( pTag, pUpdate[ iTag ], pKey ) != 0 ) + if( mixCompareKey( pTag, pUpdate[ iTag ], pKey, pTag->uiLen ) != 0 ) { HB_ULONG ulKeyPos; mixKeyFree( pTag->pKeys[ pUpdate[ iTag ] ] ); @@ -767,6 +773,7 @@ static HB_ERRCODE adsxGoTop( ADSXAREAP pArea ) static HB_ERRCODE adsxSeek( ADSXAREAP pArea, HB_BOOL bSoftSeek, PHB_ITEM pKey, HB_BOOL bFindLast ) { PMIXKEY pMixKey; + HB_USHORT uiLen; HB_ULONG ulKeyPos, ulRecNo; HB_ERRCODE errCode; HB_BOOL fFound = HB_FALSE; @@ -775,19 +782,26 @@ static HB_ERRCODE adsxSeek( ADSXAREAP pArea, HB_BOOL bSoftSeek, PHB_ITEM pKey, H return SUPER_SEEK( ( AREAP ) pArea, bSoftSeek, pKey, bFindLast ); /* TODO: pKey type validation, EG_DATATYPE runtime error */ - pMixKey = mixKeyNew( pKey, bFindLast ? ( HB_ULONG ) ( -1 ) : 0, pArea->pTagCurrent->bType, - pArea->pTagCurrent->uiLen ); + uiLen = pArea->pTagCurrent->uiLen; + pMixKey = mixKeyNew( pKey, bFindLast ? ( HB_ULONG ) ( -1 ) : 0, pArea->pTagCurrent->bType, uiLen ); + + if( pArea->pTagCurrent->bType == 'C' ) + { + HB_SIZE ul = hb_itemGetCLen( pKey ); + if( ul < ( HB_SIZE ) uiLen ) + uiLen = ( HB_USHORT ) ul; + } /* reset any pending relations - I hope ACE make the same and the problem reported in GOTO() does not exist here */ SELF_RESETREL( &pArea->adsarea ); - mixFindKey( pArea->pTagCurrent, pMixKey, &ulKeyPos ); + mixFindKeyLen( pArea->pTagCurrent, pMixKey, uiLen, &ulKeyPos ); ulRecNo = 0; if( bFindLast ) { - if( ulKeyPos > 0 && mixCompareKey( pArea->pTagCurrent, ulKeyPos - 1, pMixKey ) == -1 ) + if( ulKeyPos > 0 && mixCompareKey( pArea->pTagCurrent, ulKeyPos - 1, pMixKey, uiLen ) == -1 ) { ulRecNo = pArea->pTagCurrent->pKeys[ ulKeyPos - 1 ]->rec; fFound = HB_TRUE; @@ -803,7 +817,7 @@ static HB_ERRCODE adsxSeek( ADSXAREAP pArea, HB_BOOL bSoftSeek, PHB_ITEM pKey, H if( ulKeyPos < pArea->pTagCurrent->ulRecCount ) { ulRecNo = pArea->pTagCurrent->pKeys[ ulKeyPos ]->rec; - fFound = mixCompareKey( pArea->pTagCurrent, ulKeyPos, pMixKey ) == 1; + fFound = mixCompareKey( pArea->pTagCurrent, ulKeyPos, pMixKey, uiLen ) == 1; } } diff --git a/src/compiler/hbopt.c b/src/compiler/hbopt.c index 470378ff45..da01bf5ea2 100644 --- a/src/compiler/hbopt.c +++ b/src/compiler/hbopt.c @@ -965,20 +965,8 @@ static HB_BOOL hb_compIsUncondJump( HB_BYTE bPCode ) { return bPCode == HB_P_JUMPNEAR || bPCode == HB_P_JUMP || - bPCode == HB_P_JUMPFAR; -/* || bPCode == HB_P_SEQEND; - BEGIN SEQUENCE/END SEQUENCE logic could not be processed using conditional/unconditional - jumps. I set HB_P_SEQEND as conditional jump though this PCode instruction is processed - as unconditional jump by Harbour VM. This hack solves 'Variable is assigned but not used' - warning in code: - BEGIN SEQUENCE - nI := 1 - Break( NIL ) - RECOVER - ? nI - END SEQUENCE - [Mindaugas] - */ + bPCode == HB_P_JUMPFAR || + bPCode == HB_P_SEQEND; } #if 0 @@ -1256,7 +1244,7 @@ static void hb_compPCodeEnumSelfifyLocal( PHB_HFUNC pFunc, HB_SHORT isLocal ) } -static int hb_compPCodeTraceAssignedUnused( PHB_HFUNC pFunc, HB_SIZE nPos, HB_BYTE * pMap, HB_SHORT isLocal ) +static int hb_compPCodeTraceAssignedUnused( PHB_HFUNC pFunc, HB_SIZE nPos, HB_BYTE * pMap, HB_SHORT isLocal, HB_BOOL fCanBreak ) { for( ;; ) { @@ -1265,22 +1253,56 @@ static int hb_compPCodeTraceAssignedUnused( PHB_HFUNC pFunc, HB_SIZE nPos, HB_BY pMap[ nPos ] = 1; - if( pFunc->pCode[ nPos ] == HB_P_POPLOCAL || - pFunc->pCode[ nPos ] == HB_P_POPLOCALNEAR || - pFunc->pCode[ nPos ] == HB_P_PUSHLOCAL || - pFunc->pCode[ nPos ] == HB_P_PUSHLOCALNEAR || - pFunc->pCode[ nPos ] == HB_P_PUSHLOCALREF || - pFunc->pCode[ nPos ] == HB_P_LOCALINCPUSH || - pFunc->pCode[ nPos ] == HB_P_LOCALDEC || - pFunc->pCode[ nPos ] == HB_P_LOCALINC || - pFunc->pCode[ nPos ] == HB_P_LOCALADDINT || - pFunc->pCode[ nPos ] == HB_P_LOCALNEARADDINT ) + + if( pFunc->pCode[ nPos ] == HB_P_FUNCTION || + pFunc->pCode[ nPos ] == HB_P_FUNCTIONSHORT || + pFunc->pCode[ nPos ] == HB_P_DO || + pFunc->pCode[ nPos ] == HB_P_DOSHORT || + pFunc->pCode[ nPos ] == HB_P_SEND || + pFunc->pCode[ nPos ] == HB_P_SENDSHORT || + pFunc->pCode[ nPos ] == HB_P_MACRODO || + pFunc->pCode[ nPos ] == HB_P_MACROFUNC || + pFunc->pCode[ nPos ] == HB_P_MACROSEND ) + { + fCanBreak = HB_TRUE; + } + else if( pFunc->pCode[ nPos ] == HB_P_POPLOCAL || + pFunc->pCode[ nPos ] == HB_P_POPLOCALNEAR || + pFunc->pCode[ nPos ] == HB_P_PUSHLOCAL || + pFunc->pCode[ nPos ] == HB_P_PUSHLOCALNEAR || + pFunc->pCode[ nPos ] == HB_P_PUSHLOCALREF || + pFunc->pCode[ nPos ] == HB_P_LOCALINCPUSH || + pFunc->pCode[ nPos ] == HB_P_LOCALDEC || + pFunc->pCode[ nPos ] == HB_P_LOCALINC || + pFunc->pCode[ nPos ] == HB_P_LOCALADDINT || + pFunc->pCode[ nPos ] == HB_P_LOCALNEARADDINT ) + { if( hb_compLocalGetNumber( pFunc->pCode + nPos ) == isLocal ) { if( pFunc->pCode[ nPos ] == HB_P_POPLOCAL || pFunc->pCode[ nPos ] == HB_P_POPLOCALNEAR ) - return 0; + { + if( fCanBreak ) + { + nPos += hb_compPCodeSize( pFunc, nPos ); + while( pFunc->pCode[ nPos ] != HB_P_ENDPROC && pFunc->pCode[ nPos ] != HB_P_ENDBLOCK && + pFunc->pCode[ nPos ] != HB_P_SEQBEGIN && pFunc->pCode[ nPos ] != HB_P_SEQEND ) + { + nPos += hb_compPCodeSize( pFunc, nPos ); + } + if( pFunc->pCode[ nPos ] == HB_P_SEQEND ) + { + /* Process RECOVER */ + fCanBreak = HB_FALSE; + nPos += hb_compPCodeSize( pFunc, nPos ); + continue; + } + return 0; + } + else + return 0; + } else return 1; } @@ -1301,7 +1323,7 @@ static int hb_compPCodeTraceAssignedUnused( PHB_HFUNC pFunc, HB_SIZE nPos, HB_BY continue; } - if( hb_compPCodeTraceAssignedUnused( pFunc, nPos2, pMap, isLocal ) ) + if( hb_compPCodeTraceAssignedUnused( pFunc, nPos2, pMap, isLocal, fCanBreak ) ) return 1; } else if( pFunc->pCode[ nPos ] == HB_P_SWITCH ) /* Switch is multiplace jump */ @@ -1311,7 +1333,7 @@ static int hb_compPCodeTraceAssignedUnused( PHB_HFUNC pFunc, HB_SIZE nPos, HB_BY nPos += 3; for( us = 0; us < usCount; us++ ) { - if( hb_compPCodeTraceAssignedUnused( pFunc, nPos, pMap, isLocal ) ) + if( hb_compPCodeTraceAssignedUnused( pFunc, nPos, pMap, isLocal, fCanBreak ) ) return 1; nPos += hb_compPCodeSize( pFunc, nPos ); @@ -1423,7 +1445,7 @@ static void hb_compPCodeEnumAssignedUnused( HB_COMP_DECL, PHB_HFUNC pFunc, PHB_O pMap[ nPos ] = 1; if( ! hb_compPCodeTraceAssignedUnused( pFunc, nPos + hb_compPCodeSize( pFunc, nPos ), - pMap, isLocal ) ) + pMap, isLocal, HB_FALSE ) ) { char szFun[ 256 ]; diff --git a/src/rdd/dbf1.c b/src/rdd/dbf1.c index 18b742fd8e..87643d3691 100644 --- a/src/rdd/dbf1.c +++ b/src/rdd/dbf1.c @@ -2022,7 +2022,7 @@ static HB_ERRCODE hb_dbfGetValue( DBFAREAP pArea, HB_USHORT uiIndex, PHB_ITEM pI } /* Read record */ - if( ! pArea->fValidBuffer && ! hb_dbfReadRecord( pArea ) ) + if( ! pArea->pRecord || ! pArea->fValidBuffer && ! hb_dbfReadRecord( pArea ) ) return HB_FAILURE; if( --uiIndex >= pArea->area.uiFieldCount )