diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 3e9d5135dc..2719cb1cb5 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,19 @@ 2002-12-01 23:12 UTC+0100 Foo Bar */ +2003-01-29 22:05 UTC+0300 Alexander Kresin + * include/hberrors.h + * include/hbpcode.h + * source/compiler/genc.c + * source/compiler/harbour.sly + * source/compiler/harbour.y + * source/compiler/hbfix.c + * source/compiler/hbpcode.c + * source/vm/hvm.c + * Added new pcode HB_P_LOCALNEARADDINT for using in FOR ... NEXT cycle, + it increases the speed of execution the cycle. + Borrowed from xHarbour. + 2003-01-28 22:20 UTC+0300 Alexander Kresin * source/rdd/dbcmd.c ! Fixed a bug with APPEND FROM ..., COPY TO..., when there was a memo field diff --git a/harbour/include/hberrors.h b/harbour/include/hberrors.h index df2525295b..d79c43498a 100644 --- a/harbour/include/hberrors.h +++ b/harbour/include/hberrors.h @@ -113,6 +113,7 @@ extern "C" { #define HB_COMP_ERR_INVALID_INLINE 49 #define HB_COMP_ERR_TOOMANY_INLINE 50 #define HB_COMP_ERR_REQUIRES_C 51 +#define HB_COMP_ERR_OPTIMIZEDLOCAL_OUT_OF_RANGE 52 #define HB_COMP_WARN_AMBIGUOUS_VAR 1 #define HB_COMP_WARN_MEMVAR_ASSUMED 2 diff --git a/harbour/include/hbpcode.h b/harbour/include/hbpcode.h index 8644b62f63..a19132f90a 100644 --- a/harbour/include/hbpcode.h +++ b/harbour/include/hbpcode.h @@ -189,8 +189,9 @@ typedef enum HB_P_MACROLIST, /* 122 HB_P_MACROPUSHLIST envelope start. */ HB_P_MACROLISTEND, /* 123 HB_P_MACROPUSHLIST envelope end. */ HB_P_MPUSHSTR, /* 124 Macro compiled pushed string */ + HB_P_LOCALNEARADDINT, /* 125 Add/Subtract specified int into specified local without using the stack. */ /* NOTE: This have to be the last definition */ - HB_P_LAST_PCODE /* 125 this defines the number of defined pcodes */ + HB_P_LAST_PCODE /* 126 this defines the number of defined pcodes */ } HB_PCODE; #endif /* HB_PCODE_H_ */ diff --git a/harbour/source/compiler/genc.c b/harbour/source/compiler/genc.c index 99fbcd6851..9667a9d2f7 100644 --- a/harbour/source/compiler/genc.c +++ b/harbour/source/compiler/genc.c @@ -1814,6 +1814,24 @@ static HB_GENC_FUNC( hb_p_macrolistend ) return 1; } +#define HB_PCODE_MKSHORT( p ) ( *( SHORT * )( p ) ) +static HB_GENC_FUNC( hb_p_localnearaddint ) +{ + fprintf( cargo->yyc, "\tHB_P_LOCALNEARADDINT, %i, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], + pFunc->pCode[ lPCodePos + 3 ] ); + + if( cargo->bVerbose ) + { + fprintf( cargo->yyc, "\t/* %s %i*/", hb_compLocalVariableFind( pFunc, ( signed char ) pFunc->pCode[ lPCodePos + 1 ] )->szName, + HB_PCODE_MKSHORT( &( pFunc->pCode[ lPCodePos + 2 ] ) ) ); + } + + fprintf( cargo->yyc, "\n" ); + + return 4; +} + /* NOTE: The order of functions have to match the order of opcodes * mnemonics */ @@ -1946,8 +1964,9 @@ static HB_GENC_FUNC_PTR s_verbose_table[] = { hb_p_macrolist, hb_p_macrolistend, /* start: more pcodes generated by macro compiler */ - hb_p_dummy + hb_p_dummy, /* end: */ + hb_p_localnearaddint }; static void hb_compGenCReadable( PFUNCTION pFunc, FILE * yyc ) diff --git a/harbour/source/compiler/harbour.sly b/harbour/source/compiler/harbour.sly index d1174debf0..22bdeeac80 100644 --- a/harbour/source/compiler/harbour.sly +++ b/harbour/source/compiler/harbour.sly @@ -1738,11 +1738,40 @@ ForNext : FOR LValue ForAssign Expression /* 1 2 3 4 */ } ForStatements /* 12 */ { + short iStep, iLocal; + hb_compLoopHere(); + if( $8 ) - hb_compExprClear( hb_compExprGenStatement( hb_compExprSetOperand( hb_compExprNewPlusEq( $2 ), $8 ) ) ); + { + if( $8->ExprType == HB_ET_NUMERIC && $8->value.asNum.NumType == HB_ET_LONG && + $8->value.asNum.lVal >= -32768 && $8->value.asNum.lVal <= 32767 ) + { + iStep = ( short ) $8->value.asNum.lVal; + } + else + { + iStep = 0; + } + } else + { + iStep = 1; + } + + if( iStep && ( iLocal = hb_compLocalGetPos( $2->value.asSymbol ) ) > 0 && iLocal < 256 ) + { + hb_compGenPCode4( HB_P_LOCALNEARADDINT, ( BYTE ) iLocal, HB_LOBYTE( iStep ), HB_HIBYTE( iStep ), ( BOOL ) 0 ); + } + else if( $8 ) + { + hb_compExprClear( hb_compExprGenStatement( hb_compExprSetOperand( hb_compExprNewPlusEq( $2 ), $8 ) ) ); + } + else + { hb_compExprClear( hb_compExprGenStatement( hb_compExprNewPreInc( $2 ) ) ); + } + hb_compGenJump( $9 - hb_comp_functions.pLast->lPCodePos ); hb_compGenJumpHere( $11 ); hb_compLoopEnd(); diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 1d3e8f0d14..ce47f18d16 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -1522,11 +1522,40 @@ ForNext : FOR LValue ForAssign Expression /* 1 2 3 4 */ } ForStatements /* 12 */ { + short iStep, iLocal; + hb_compLoopHere(); + if( $8 ) - hb_compExprClear( hb_compExprGenStatement( hb_compExprSetOperand( hb_compExprNewPlusEq( $2 ), $8 ) ) ); + { + if( $8->ExprType == HB_ET_NUMERIC && $8->value.asNum.NumType == HB_ET_LONG && + $8->value.asNum.lVal >= -32768 && $8->value.asNum.lVal <= 32767 ) + { + iStep = ( short ) $8->value.asNum.lVal; + } + else + { + iStep = 0; + } + } else + { + iStep = 1; + } + + if( iStep && ( iLocal = hb_compLocalGetPos( $2->value.asSymbol ) ) > 0 && iLocal < 256 ) + { + hb_compGenPCode4( HB_P_LOCALNEARADDINT, ( BYTE ) iLocal, HB_LOBYTE( iStep ), HB_HIBYTE( iStep ), ( BOOL ) 0 ); + } + else if( $8 ) + { + hb_compExprClear( hb_compExprGenStatement( hb_compExprSetOperand( hb_compExprNewPlusEq( $2 ), $8 ) ) ); + } + else + { hb_compExprClear( hb_compExprGenStatement( hb_compExprNewPreInc( $2 ) ) ); + } + hb_compGenJump( $9 - hb_comp_functions.pLast->lPCodePos ); hb_compGenJumpHere( $11 ); hb_compLoopEnd(); diff --git a/harbour/source/compiler/hbfix.c b/harbour/source/compiler/hbfix.c index fe05afbc9a..73d0964f78 100644 --- a/harbour/source/compiler/hbfix.c +++ b/harbour/source/compiler/hbfix.c @@ -248,6 +248,33 @@ static HB_FIX_FUNC( hb_p_staticname ) return (USHORT) (lPCodePos - ulStart + 1) ; } +static HB_FIX_FUNC( hb_p_localnearaddint ) +{ + BYTE cVarId = pFunc->pCode[ lPCodePos + 1 ]; + USHORT wNewId; + + HB_SYMBOL_UNUSED( cargo ); + + if( pFunc->wParamCount ) + { + if( ( wNewId = cVarId + pFunc->wParamCount ) < 256 ) + { + pFunc->pCode[ lPCodePos + 1 ] = (BYTE) wNewId; + } + else + { + // After fixing this variable cannot be accessed using near code + char sTemp[16]; + + sprintf( (char *) sTemp, "%i", pFunc->wParamCount ); + hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_OPTIMIZEDLOCAL_OUT_OF_RANGE, "HB_P_LOCALNEARADDINT", (const char *) sTemp ); + } + } + + return (USHORT) 4; +} + + /* NOTE: The order of functions have to match the order of opcodes * mnemonics */ @@ -380,7 +407,8 @@ static HB_FIX_FUNC_PTR s_fixlocals_table[] = NULL, /* HB_P_ONE, */ NULL, /* HB_P_MACROLIST, */ NULL, /* HB_P_MACROLISTEND, */ - NULL /* HB_P_MPUSHSTR */ + NULL, /* HB_P_MPUSHSTR */ + hb_p_localnearaddint /* HB_P_LOCALNEARADDINT, */ }; void hb_compFixFuncPCode( PFUNCTION pFunc ) diff --git a/harbour/source/compiler/hbpcode.c b/harbour/source/compiler/hbpcode.c index 8b6cea71d2..88e3f3dd0f 100644 --- a/harbour/source/compiler/hbpcode.c +++ b/harbour/source/compiler/hbpcode.c @@ -169,7 +169,8 @@ static BYTE s_pcode_len[] = { 1, /* HB_P_ONE, */ 1, /* HB_P_MACROLIST, */ 1, /* HB_P_MACROLISTEND, */ - 0 /* HB_P_MPUSHSTR */ + 0, /* HB_P_MPUSHSTR */ + 4 /* HB_P_LOCALNEARADDINT, */ }; static PVAR hb_compPrivateFind( char * szPrivateName ) diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index beafa79238..7d4c50f515 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -1580,6 +1580,78 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) break; } + case HB_P_LOCALNEARADDINT: + HB_TRACE( HB_TR_DEBUG, ("HB_P_LOCALNEARADDINT") ); + { + #define HB_PCODE_MKSHORT( p ) ( *( SHORT * )( p ) ) + PHB_ITEM pLocal = hb_stackItemFromBase( pCode[ w + 1 ] ); + short iAdd = HB_PCODE_MKSHORT( &( pCode[ w + 2 ] ) ); + double dNewVal; + + w += 4; + + if( HB_IS_BYREF( pLocal ) ) + { + pLocal = hb_itemUnRef( pLocal ); + } + + if( pLocal->type & HB_IT_INTEGER ) + { + dNewVal = pLocal->item.asInteger.value + iAdd; + } + else if( pLocal->type & HB_IT_LONG ) + { + dNewVal = pLocal->item.asLong.value + iAdd; + } + else if( pLocal->type & HB_IT_DOUBLE ) + { + dNewVal = pLocal->item.asDouble.value + iAdd; + } + else if( HB_IS_DATE( pLocal ) ) + { + pLocal->item.asDate.value += iAdd; + break; + } + else + { + PHB_ITEM pAdd = hb_itemPutNI( NULL, ( int ) iAdd ); + PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1081, NULL, "+", 2, pLocal, pAdd ); + + hb_itemRelease( pAdd ); + + if( pResult ) + { + hb_itemMove( pLocal, pResult ); + } + + break; + } + + if( pLocal->type & HB_IT_DOUBLE ) + { + pLocal->item.asDouble.value = dNewVal; + } + else if( SHRT_MIN <= dNewVal && dNewVal <= SHRT_MAX ) + { + pLocal->type = HB_IT_INTEGER; + pLocal->item.asInteger.value = ( int ) dNewVal; + } + else if( LONG_MIN <= dNewVal && dNewVal <= LONG_MAX ) + { + pLocal->type = HB_IT_LONG; + pLocal->item.asLong.value = ( long ) dNewVal; + } + else + { + pLocal->type = HB_IT_DOUBLE; + pLocal->item.asDouble.value = dNewVal; + pLocal->item.asDouble.length = ( dNewVal >= 10000000000.0 || dNewVal <= -1000000000.0 ) ? 20 : 10; + pLocal->item.asDouble.decimal = hb_set.HB_SET_DECIMALS; + } + + break; + } + /* misc */ case HB_P_NOOP: