diff --git a/harbour/ChangeLog b/harbour/ChangeLog index d99caa73ef..7898b8ec8b 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,36 @@ +20000421-14:20 GMT-8 Ron Pinkas + + * source/compiler/hvm.c + + Added support for new PCodes HB_P_PUSHBYTE, and HB_P_PUSHONE + + Added void hb_vmPushOne( void ), void hb_vmPushZero( void ) and void hb_vmPushByte( BYTE ) + * Optimized HB_P_ZERO by using hb_vmPushZero() + + * source/compiler/harbour.c + - REMMED not used hb_compGenPushInteger() + * Optimized hb_compGenPushLong() to USE HB_P_ZERO, HB_P_ONE, HB_P_PUSHBBYTE, HB_P_PUSHBINT, or , HB_P_PUSHLONG as needed. + * Optimized few pairs of hb_compGenPCode1() to use hb_compGenPCode2() instead. + + * source/compiler/genc.c + + Added support for PCodes HB_P_PUSHBYTE, and HB_P_PUSHONE + + * source/compiler/hbpcode.c + + Added hb_compGenPCode2( BYTE, BYTE ) + + * source/compiler/harbour.y + * Optimized few pairs of hb_compGenPCode1() to use hb_compGenPCode2() instead. + + * source/include/hbpcode.h + + Added PCodes HB_P_PUSHBYTE, and HB_P_PUSHONE + + * source/include/hbvm.h + + Added: + extern void hb_vmPushOne( void ); /* pushes a 0 onto the stack */ + extern void hb_vmPushZero( void ); /* pushes a 1 onto the stack */ + extern void hb_vmPushByte( BYTE bNumber ); /* pushes a integer number onto the stack */ + + * include/hbcomp.h + - Removed #ifef of GenObj32 + 20000421-21:56 GMT+2 Maurilio Longo * include/hbcomp.h diff --git a/harbour/include/hbcomp.h b/harbour/include/hbcomp.h index 8348967634..50ecd19aaf 100644 --- a/harbour/include/hbcomp.h +++ b/harbour/include/hbcomp.h @@ -215,6 +215,7 @@ extern void hb_compGenPushAliasedVar( char *, BOOL, char *, long, HB_MACRO_DECL extern void hb_compGenPopAliasedVar( char *, BOOL, char *, long, HB_MACRO_DECL ); extern void hb_compGenPushFunRef( char *, HB_MACRO_DECL ); extern void hb_compGenPCode1( BYTE, HB_MACRO_DECL ); /* generates 1 byte of pcode */ +extern void hb_compGenPCode2( BYTE, BYTE, HB_MACRO_DECL ); /* generates 2 bytes of pcode */ extern void hb_compGenPCode3( BYTE, BYTE, BYTE, HB_MACRO_DECL ); /* generates 3 bytes of pcode */ extern void hb_compGenPCodeN( BYTE * pBuffer, ULONG ulSize, HB_MACRO_DECL ); /* copy bytes to a pcode buffer */ @@ -263,6 +264,7 @@ extern void hb_compGenPushAliasedVar( char *, BOOL, char *, long ); extern void hb_compGenPopAliasedVar( char *, BOOL, char *, long ); extern void hb_compGenPushFunRef( char * ); extern void hb_compGenPCode1( BYTE ); /* generates 1 byte of pcode */ +extern void hb_compGenPCode2( BYTE, BYTE ); /* generates 2 bytes of pcode */ extern void hb_compGenPCode3( BYTE, BYTE, BYTE ); /* generates 3 bytes of pcode */ extern void hb_compGenPCodeN( BYTE * pBuffer, ULONG ulSize ); /* copy bytes to a pcode buffer */ @@ -318,9 +320,7 @@ extern void hb_compGenJava( PHB_FNAME ); /* generates the Java language ou extern void hb_compGenPascal( PHB_FNAME ); /* generates the Pascal language output */ extern void hb_compGenRC( PHB_FNAME ); /* generates the RC language output */ extern void hb_compGenPortObj( PHB_FNAME ); /* generates the portable objects */ -#ifdef HARBOUR_OBJ_GENERATION extern void hb_compGenObj32( PHB_FNAME ); /* generates OBJ 32 bits */ -#endif /* variable used by compiler */ @@ -343,7 +343,7 @@ extern BOOL hb_comp_bAutoMemvarAssume; extern BOOL hb_comp_bForceMemvars; extern BOOL hb_comp_bDebugInfo; extern char hb_comp_szPrefix[ 20 ]; -extern BOOL hb_comp_iGenCOutput; +extern int hb_comp_iGenCOutput; extern int hb_comp_iExitLevel; extern int hb_comp_iFunctionCnt; extern char hb_comp_cVarType; diff --git a/harbour/include/hbpcode.h b/harbour/include/hbpcode.h index 3542bf3123..ffd7f1c6cf 100644 --- a/harbour/include/hbpcode.h +++ b/harbour/include/hbpcode.h @@ -122,6 +122,7 @@ typedef enum HB_P_PUSHALIASEDVAR, /* pushes aliased variable (either a field or a memvar) */ HB_P_PUSHBLOCK, /* start of a codeblock definition */ HB_P_PUSHFIELD, /* pushes unaliased field */ + HB_P_PUSHBYTE, /* places a 1 byte integer number on the virtual machine stack */ HB_P_PUSHINT, /* places an integer number on the virtual machine stack */ HB_P_PUSHLOCAL, /* pushes the contains of a local variable to the virtual machine stack */ HB_P_PUSHLOCALREF, /* pushes a local variable by reference to the virtual machine stack */ @@ -144,7 +145,8 @@ typedef enum HB_P_STATICS, /* defines the number of statics variables for a PRG */ HB_P_SWAPALIAS, /* restores the current workarea number from the eval stack */ HB_P_TRUE, /* pushes true on the virtual machine stack */ - HB_P_ZERO /* places a zero on the virtual machine stack */ + HB_P_ZERO, /* places a ZERO on the virtual machine stack */ + HB_P_ONE /* places a ONE on the virtual machine stack */ } HB_PCODE; #endif /* HB_PCODE_H_ */ diff --git a/harbour/include/hbvm.h b/harbour/include/hbvm.h index bd258193b7..ae34329359 100644 --- a/harbour/include/hbvm.h +++ b/harbour/include/hbvm.h @@ -77,6 +77,9 @@ extern void hb_vmFunction( USHORT uiParams ); /* executes a function saving i extern void hb_vmPush( PHB_ITEM pItem ); /* pushes a generic item onto the stack */ extern void hb_vmPushNil( void ); /* in this case it places nil at self */ extern void hb_vmPushNumber( double dNumber, int iDec ); /* pushes a number on to the stack and decides if it is integer, long or double */ +extern void hb_vmPushOne( void ); /* pushes a 0 onto the stack */ +extern void hb_vmPushZero( void ); /* pushes a 1 onto the stack */ +extern void hb_vmPushByte( BYTE bNumber ); /* pushes a integer number onto the stack */ extern void hb_vmPushInteger( int iNumber ); /* pushes a integer number onto the stack */ extern void hb_vmPushLong( long lNumber ); /* pushes a long number onto the stack */ extern void hb_vmPushDouble( double lNumber, int iDec ); /* pushes a double number onto the stack */ diff --git a/harbour/source/compiler/genc.c b/harbour/source/compiler/genc.c index ec5ef73df8..95f92279d0 100644 --- a/harbour/source/compiler/genc.c +++ b/harbour/source/compiler/genc.c @@ -932,6 +932,15 @@ static void hb_compGenCReadable( PFUNCTION pFunc ) } break; + case HB_P_PUSHBYTE: + fprintf( s_yyc, "\tHB_P_PUSHBYTE, %i,", + pFunc->pCode[ lPCodePos + 1 ] ); + if( bVerbose ) fprintf( s_yyc, "\t/* %i */", + pFunc->pCode[ lPCodePos + 1 ] ); + fprintf( s_yyc, "\n" ); + lPCodePos += 2; + break; + case HB_P_PUSHINT: fprintf( s_yyc, "\tHB_P_PUSHINT, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], @@ -1243,6 +1252,11 @@ static void hb_compGenCReadable( PFUNCTION pFunc ) lPCodePos++; break; + case HB_P_ONE: + fprintf( s_yyc, "\tHB_P_ONE,\n" ); + lPCodePos++; + break; + case HB_P_ZERO: fprintf( s_yyc, "\tHB_P_ZERO,\n" ); lPCodePos++; diff --git a/harbour/source/compiler/harbour.c b/harbour/source/compiler/harbour.c index b6ff2f469a..7818764801 100644 --- a/harbour/source/compiler/harbour.c +++ b/harbour/source/compiler/harbour.c @@ -2224,27 +2224,49 @@ void hb_compGenPushFunCall( char * szFunName ) } /* generates the pcode to push a integer number on the virtual machine stack */ +/* void hb_compGenPushInteger( int iNumber ) { - if( iNumber ) - hb_compGenPCode3( HB_P_PUSHINT, HB_LOBYTE( ( USHORT ) iNumber ), HB_HIBYTE( ( USHORT ) iNumber ) ); - else + if( lNumber == 0 ) hb_compGenPCode1( HB_P_ZERO ); + else if ( lNumber == 1 ) + hb_compGenPCode1( HB_P_ONE ); + else if ( ( ( char * ) &lNumber )[ 2 ] == 0 && ( ( char * ) &lNumber )[ 3 ] == 0 ) + { + if ( ( ( char * ) &lNumber )[ 1 ] == 0 ) + hb_compGenPCode2( HB_P_PUSHBYTE, ( ( char * ) &lNumber )[ 0 ] ); + else + hb_compGenPCode3( HB_P_PUSHINT, ( ( char * ) &lNumber )[ 0 ], ( ( char * ) &lNumber )[ 1 ] ); + } + else + { + hb_compGenPCode1( HB_P_PUSHLONG ); + hb_compGenPCode2( ( ( char * ) &lNumber )[ 0 ], ( ( char * ) &lNumber )[ 1 ] ); + hb_compGenPCode2( ( ( char * ) &lNumber )[ 2 ], ( ( char * ) &lNumber )[ 3 ] ); + } } +*/ /* generates the pcode to push a long number on the virtual machine stack */ void hb_compGenPushLong( long lNumber ) { - if( lNumber ) + if( lNumber == 0 ) + hb_compGenPCode1( HB_P_ZERO ); + else if ( lNumber == 1 ) + hb_compGenPCode1( HB_P_ONE ); + else if ( ( ( char * ) &lNumber )[ 2 ] == 0 && ( ( char * ) &lNumber )[ 3 ] == 0 ) { - hb_compGenPCode1( HB_P_PUSHLONG ); - hb_compGenPCode1( ( ( char * ) &lNumber )[ 0 ] ); - hb_compGenPCode1( ( ( char * ) &lNumber )[ 1 ] ); - hb_compGenPCode1( ( ( char * ) &lNumber )[ 2 ] ); - hb_compGenPCode1( ( ( char * ) &lNumber )[ 3 ] ); + if ( ( ( char * ) &lNumber )[ 1 ] == 0 ) + hb_compGenPCode2( HB_P_PUSHBYTE, ( ( char * ) &lNumber )[ 0 ] ); + else + hb_compGenPCode3( HB_P_PUSHINT, ( ( char * ) &lNumber )[ 0 ], ( ( char * ) &lNumber )[ 1 ] ); } else - hb_compGenPCode1( HB_P_ZERO ); + { + hb_compGenPCode1( HB_P_PUSHLONG ); + hb_compGenPCode2( ( ( char * ) &lNumber )[ 0 ], ( ( char * ) &lNumber )[ 1 ] ); + hb_compGenPCode2( ( ( char * ) &lNumber )[ 2 ], ( ( char * ) &lNumber )[ 3 ] ); + } } /* generates the pcode to push a string on the virtual machine stack */ diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index dd277db31c..a1c4768873 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -331,8 +331,7 @@ Statement : ExecFlow CrlfStmnt { } hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_EXIT_IN_SEQUENCE, "RETURN", NULL ); } hb_compExprGenPush( $3 ); /* TODO: check if return value agree with declared value */ - hb_compGenPCode1( HB_P_RETVALUE ); - hb_compGenPCode1( HB_P_ENDPROC ); + hb_compGenPCode2( HB_P_RETVALUE, HB_P_ENDPROC ); if( hb_comp_functions.pLast->bFlags & FUN_PROCEDURE ) { /* procedure returns a value */ hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_PROC_RETURN_VALUE, NULL, NULL ); @@ -1367,8 +1366,7 @@ RecoverEmpty : RECOVER hb_comp_functions.pLast->bFlags &= ~ FUN_BREAK_CODE; $$ = hb_comp_functions.pLast->lPCodePos; --hb_comp_wSeqCounter; - hb_compGenPCode1( HB_P_SEQRECOVER ); - hb_compGenPCode1( HB_P_POP ); + hb_compGenPCode2( HB_P_SEQRECOVER, HB_P_POP ); } ; diff --git a/harbour/source/compiler/hbpcode.c b/harbour/source/compiler/hbpcode.c index 2fa07fbcd8..316582f4f0 100644 --- a/harbour/source/compiler/hbpcode.c +++ b/harbour/source/compiler/hbpcode.c @@ -52,6 +52,24 @@ void hb_compGenPCode1( BYTE byte ) pFunc->pCode[ pFunc->lPCodePos++ ] = byte; } +void hb_compGenPCode2( BYTE byte1, BYTE byte2 ) +{ + PFUNCTION pFunc = hb_comp_functions.pLast; /* get the currently defined Clipper function */ + + if( ! pFunc->pCode ) /* has been created the memory block to hold the pcode ? */ + { + pFunc->pCode = ( BYTE * ) hb_xgrab( HB_PCODE_CHUNK ); + pFunc->lPCodeSize = HB_PCODE_CHUNK; + pFunc->lPCodePos = 0; + } + else + if( ( pFunc->lPCodeSize - pFunc->lPCodePos ) < 2 ) + pFunc->pCode = ( BYTE * ) hb_xrealloc( pFunc->pCode, pFunc->lPCodeSize += HB_PCODE_CHUNK ); + + pFunc->pCode[ pFunc->lPCodePos++ ] = byte1; + pFunc->pCode[ pFunc->lPCodePos++ ] = byte2; +} + void hb_compGenPCode3( BYTE byte1, BYTE byte2, BYTE byte3 ) { PFUNCTION pFunc = hb_comp_functions.pLast; /* get the currently defined Clipper function */ diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index f9b09a2ab2..539909e7c1 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -855,8 +855,13 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols ) w++; break; + case HB_P_ONE: + hb_vmPushOne(); + w++; + break; + case HB_P_ZERO: - hb_vmPushInteger( 0 ); + hb_vmPushZero(); w++; break; @@ -867,6 +872,11 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols ) w++; break; + case HB_P_PUSHBYTE: + hb_vmPushByte( ( BYTE ) pCode[ w + 1 ] ); + w += 2; + break; + case HB_P_PUSHINT: hb_vmPushInteger( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); w += 3; @@ -2324,15 +2334,15 @@ static void hb_vmArrayPush( void ) { hb_arrayGet( pArray, ulIndex, pArray ); hb_stackPop(); - + /* Looks like this without optimization: - + HB_ITEM item; - + hb_arrayGet( pArray, ulIndex, &item ); hb_stackPop(); hb_stackPop(); - + hb_itemCopy( hb_stack.pPos, &item ); hb_itemClear( &item ); hb_stackPush(); @@ -2945,6 +2955,36 @@ void hb_vmPushNumber( double dNumber, int iDec ) hb_vmPushDouble( dNumber, hb_set.HB_SET_DECIMALS ); } +void hb_vmPushOne( void ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_vmPushOne()")); + + hb_stack.pPos->type = HB_IT_INTEGER; + hb_stack.pPos->item.asInteger.value = ( BYTE ) 1; + hb_stack.pPos->item.asInteger.length = 10; + hb_stackPush(); +} + +void hb_vmPushZero( void ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_vmPushZero()")); + + hb_stack.pPos->type = HB_IT_INTEGER; + hb_stack.pPos->item.asInteger.value = ( BYTE ) 0; + hb_stack.pPos->item.asInteger.length = 10; + hb_stackPush(); +} + +void hb_vmPushByte( BYTE bNumber ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_vmPushInteger(%i)", bNumber)); + + hb_stack.pPos->type = HB_IT_INTEGER; + hb_stack.pPos->item.asInteger.value = bNumber; + hb_stack.pPos->item.asInteger.length = 10; + hb_stackPush(); +} + void hb_vmPushInteger( int iNumber ) { HB_TRACE(HB_TR_DEBUG, ("hb_vmPushInteger(%d)", iNumber));