20000419-05:30 GMT-8 Ron Pinkas <Ron@Profit-Master.com>

* source/compiler/hvm.c
     + Added PCodes HB_P_JAMPSHORT, HB_P_JAMPSHORTFALSE and HB_P_JAMPSHORTTRUE

   * source/compiler/harbour.c
     + Added hb_compOptimizeJumps() - Jumps Optimizer.
     + Added hb_compSort_ULONG() Call back function for qsort - used in the Jump Optimizer.
     + Added support for new elements of _FUNC.
     * Modified hb_compGen*Jump*() to support Short Normal and Far Jumps.

   * source/include/hbexprb.c
     * Reverted handling of .OR. .AND. and IIF() to use default (FAR) JUMPs - note the use of (0) when calling hb_compGenJump*().

   * source/compiler/genc.c
     + Added support for HB_P_JAMPSHORT, HB_P_JAMPSHORTFALSE and HB_P_JAMPSHORTTRUE

   * source/compiler/cmdcheck.c
     + Added support for new switch -J[0|1] default is J1 which enables the Jump Optimizer - Use -J0 to disable.

   * source/compiler/hbgenerr.c
     - Removed following errors:
        "Jump offset too long for HB_P_JUMP needed HB_P_JUMPFAR",
        "Jump offset too long for HB_P_JUMPTRUE needed HB_P_JUMPFARTRUE",
        "Jump offset too long for HB_P_JUMPFALSE needed HB_P_JUMPFARFALSE",

     * Changed "HB_P_JUMPx not found when fixing offset" to "Jump PCode not found"

   * source/include/hberrors.h
     - Removed following defines:
   	#define HB_COMP_ERR_INVALID_JUMPTRUE            46
   	#define HB_COMP_ERR_INVALID_JUMPFALSE           47
   	#define HB_COMP_ERR_JUMP_NOT_FOUND              48

   * source/include/hberrors.h
     + Added following to __FUNC
   	ULONG  * pNOOPs;                 /* pointer to the NOOP array */
   	ULONG  * pJumps;                 /* pointer to the Jumps array */
   	int    iNOOPs;                   /* NOOPs Counter */
   	int    iJumps;                   /* Jumps Counter */

   * source/include/hbpcode.h
     + Added HB_P_JAMPSHORT, HB_P_JAMPSHORTFALSE and HB_P_JAMPSHORTTRUE
This commit is contained in:
Ron Pinkas
2000-04-18 12:41:08 +00:00
parent 5e232fc501
commit 68f8243cbe
13 changed files with 886 additions and 194 deletions

View File

@@ -1,3 +1,47 @@
20000419-05:30 GMT-8 Ron Pinkas <Ron@Profit-Master.com>
* source/compiler/hvm.c
+ Added PCodes HB_P_JAMPSHORT, HB_P_JAMPSHORTFALSE and HB_P_JAMPSHORTTRUE
* source/compiler/harbour.c
+ Added hb_compOptimizeJumps() - Jumps Optimizer.
+ Added hb_compSort_ULONG() Call back function for qsort - used in the Jump Optimizer.
+ Added support for new elements of _FUNC.
* Modified hb_compGen*Jump*() to support Short Normal and Far Jumps.
* source/include/hbexprb.c
* Reverted handling of .OR. .AND. and IIF() to use default (FAR) JUMPs - note the use of (0) when calling hb_compGenJump*().
* source/compiler/genc.c
+ Added support for HB_P_JAMPSHORT, HB_P_JAMPSHORTFALSE and HB_P_JAMPSHORTTRUE
* source/compiler/cmdcheck.c
+ Added support for new switch -J[0|1] default is J1 which enables the Jump Optimizer - Use -J0 to disable.
* source/compiler/hbgenerr.c
- Removed following errors:
"Jump offset too long for HB_P_JUMP needed HB_P_JUMPFAR",
"Jump offset too long for HB_P_JUMPTRUE needed HB_P_JUMPFARTRUE",
"Jump offset too long for HB_P_JUMPFALSE needed HB_P_JUMPFARFALSE",
* Changed "HB_P_JUMPx not found when fixing offset" to "Jump PCode not found"
* source/include/hberrors.h
- Removed following defines:
#define HB_COMP_ERR_INVALID_JUMPTRUE 46
#define HB_COMP_ERR_INVALID_JUMPFALSE 47
#define HB_COMP_ERR_JUMP_NOT_FOUND 48
* source/include/hberrors.h
+ Added following to __FUNC
ULONG * pNOOPs; /* pointer to the NOOP array */
ULONG * pJumps; /* pointer to the Jumps array */
int iNOOPs; /* NOOPs Counter */
int iJumps; /* Jumps Counter */
* source/include/hbpcode.h
+ Added HB_P_JAMPSHORT, HB_P_JAMPSHORTFALSE and HB_P_JAMPSHORTTRUE
20000418-13:30 GMT+1 Ryszard Glab <rglab@imid.med.pl>
*include/hbapigt.h
@@ -14,8 +58,8 @@
modules - this will allow to use native (optimized) method
of box drawing (xterm!)
*full implementation of low level hb_gt_Replicate()
*added hb_gt_HorizLine() and hb_gt_VertLine() - this can be
extended by definition of HB_LINE() or
*added hb_gt_HorizLine() and hb_gt_VertLine() - this can be
extended by definition of HB_LINE() or
@ row,left,right LINE command (this will get line drawing
support on platforms where @ ... BOX command is not suitable)
@@ -24,7 +68,7 @@
*source/rtl/gtcrs/gtcrs.c
*support for box drawing added for xterm
NOTE: Only
NOTE: Only
@ y1,x1 TO y2,x2
and
@ y1,x1 TO y2,x2 DOUBLE
@@ -33,10 +77,10 @@
used in current font
(Well I am not so familiar with it then this needs some
more work - I can be wrong here :)
If you want a single method of box drawing for all platforms use
@ y1,x1 TO y2,x2
20000418-00:42 DST Paul Tucker <ptucker@sympatico.ca>
* makefile.vc

View File

@@ -165,6 +165,8 @@ rem if "%HB_GT_LIB%" == "" set HB_GT_LIB=
if "%HB_COMPILER%" == "rsxnt" gcc %1.c -Zwin32 %CFLAGS% -I..\include -L..\lib -ltools -ldebug -lvm -lrtl -l%HB_GT_LIB% -llang -lrdd -lrtl -lvm -lmacro -lpp -ldbfntx -ldbfcdx -lcommon
if "%HB_COMPILER%" == "msvc" cl -Fd..\bin\harbour -w -Zi -TP -GZ -GA %CFLAGS% -I..\include %1.c /link /subsystem:CONSOLE ..\lib\tools.lib ..\lib\debug.lib ..\lib\vm.lib ..\lib\rtl.lib ..\lib\%HB_GT_LIB%.lib ..\lib\lang.lib ..\lib\rdd.lib ..\lib\macro.lib ..\lib\pp.lib ..\lib\dbfntx.lib ..\lib\dbfcdx.lib ..\lib\common.lib user32.lib
if "%HB_COMPILER%" == "msvc" echo Ignore LNK4033 warning
if "%HB_GT_LIB%" == "gtwin" set HB_GT_LIB=
goto END
:A_OS2

View File

@@ -102,21 +102,25 @@ typedef struct _VAR
/* structure to hold a Clipper defined function */
typedef struct __FUNC
{
char * szName; /* name of a defined Clipper function */
char cScope; /* scope of a defined Clipper function */
BYTE bFlags; /* some flags we may need */
USHORT wParamCount; /* number of declared parameters */
USHORT wParamNum; /* current parameter number */
PVAR pLocals; /* pointer to local variables list */
PVAR pStatics; /* pointer to static variables list */
PVAR pFields; /* pointer to fields variables list */
PVAR pMemvars; /* pointer to memvar variables list */
BYTE * pCode; /* pointer to a memory block where pcode is stored */
ULONG lPCodeSize; /* total memory size for pcode */
ULONG lPCodePos; /* actual pcode offset */
int iStaticsBase; /* base for this function statics */
struct __FUNC * pOwner; /* pointer to the function/procedure that owns the codeblock */
struct __FUNC * pNext; /* pointer to the next defined function */
char * szName; /* name of a defined Clipper function */
char cScope; /* scope of a defined Clipper function */
BYTE bFlags; /* some flags we may need */
USHORT wParamCount; /* number of declared parameters */
USHORT wParamNum; /* current parameter number */
PVAR pLocals; /* pointer to local variables list */
PVAR pStatics; /* pointer to static variables list */
PVAR pFields; /* pointer to fields variables list */
PVAR pMemvars; /* pointer to memvar variables list */
BYTE * pCode; /* pointer to a memory block where pcode is stored */
ULONG lPCodeSize; /* total memory size for pcode */
ULONG lPCodePos; /* actual pcode offset */
int iStaticsBase; /* base for this function statics */
ULONG * pNOOPs; /* pointer to the NOOP array */
ULONG * pJumps; /* pointer to the Jumps array */
int iNOOPs; /* NOOPs Counter */
int iJumps; /* Jumps Counter */
struct __FUNC * pOwner; /* pointer to the function/procedure that owns the codeblock */
struct __FUNC * pNext; /* pointer to the next defined function */
} _FUNC, * PFUNCTION;
/* structure to control all Clipper defined functions */
@@ -357,6 +361,7 @@ extern BOOL hb_comp_bCredits;
extern BOOL hb_comp_bLogo;
extern BOOL hb_comp_bSyntaxCheckOnly;
extern int hb_comp_iLanguage;
extern int hb_comp_iJumpOptimize;
extern USHORT hb_comp_wSeqCounter;
extern USHORT hb_comp_wForCounter;

View File

@@ -89,10 +89,7 @@ extern "C" {
#define HB_COMP_ERR_BAD_MACRO 42
#define HB_COMP_ERR_INVALID_SEND 43
#define HB_COMP_ERR_FUNC_ANNOUNCE 44
#define HB_COMP_ERR_INVALID_JUMP 45
#define HB_COMP_ERR_INVALID_JUMPTRUE 46
#define HB_COMP_ERR_INVALID_JUMPFALSE 47
#define HB_COMP_ERR_JUMP_NOT_FOUND 48
#define HB_COMP_ERR_JUMP_NOT_FOUND 45
#define HB_COMP_WARN_AMBIGUOUS_VAR 1
#define HB_COMP_WARN_MEMVAR_ASSUMED 2

View File

@@ -648,11 +648,11 @@ static HB_EXPR_FUNC( hb_compExprUseIIF )
HB_EXPR_PTR pExpr = pSelf->value.asList.pExprList;
HB_EXPR_USE( pExpr, HB_EA_PUSH_PCODE );
lPosFalse = HB_EXPR_PCODE1( hb_compGenJumpFalse, -1 );
lPosFalse = HB_EXPR_PCODE1( hb_compGenJumpFalse, 0 );
pExpr =pExpr->pNext;
HB_EXPR_USE( pExpr, HB_EA_PUSH_PCODE );
lPosEnd = HB_EXPR_PCODE1( hb_compGenJump, -1 );
lPosEnd = HB_EXPR_PCODE1( hb_compGenJump, 0 );
pExpr =pExpr->pNext;
HB_EXPR_PCODE1( hb_compGenJumpHere, lPosFalse );
@@ -1993,7 +1993,7 @@ static HB_EXPR_FUNC( hb_compExprUseOr )
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_DUPLICATE );
lEndPos = HB_EXPR_PCODE1( hb_compGenJumpTrue, -1 );
lEndPos = HB_EXPR_PCODE1( hb_compGenJumpTrue, 0 );
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_OR );
HB_EXPR_PCODE1( hb_compGenJumpHere, lEndPos );
@@ -2063,7 +2063,7 @@ static HB_EXPR_FUNC( hb_compExprUseAnd )
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_DUPLICATE );
lEndPos = HB_EXPR_PCODE1( hb_compGenJumpFalse, -1 );
lEndPos = HB_EXPR_PCODE1( hb_compGenJumpFalse, 0 );
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_AND );
HB_EXPR_PCODE1( hb_compGenJumpHere, lEndPos );

View File

@@ -61,10 +61,13 @@ typedef enum
HB_P_DUPLTWO, /* places a copy of the latest two virtual machine stack value on to the stack */
HB_P_INC, /* increments the latest value on the virtual machine stack */
HB_P_INSTRING, /* checks if the second latest value on the stack is a substring of the latest one */
HB_P_JUMP, /* jumps to a relative offset */
HB_P_JUMPFAR, /* jumps to a relative offset */
HB_P_JUMPSHORT, /* jumps to a relative offset 1 Byte */
HB_P_JUMP, /* jumps to a relative offset 2 Bytes */
HB_P_JUMPFAR, /* jumps to a relative offset 3 Bytes */
HB_P_JUMPSHORTFALSE, /* checks a logic expression of the stack and jumps to a relative offset */
HB_P_JUMPFALSE, /* checks a logic expression of the stack and jumps to a relative offset */
HB_P_JUMPFARFALSE, /* checks a logic expression of the stack and jumps to a relative offset */
HB_P_JUMPSHORTTRUE, /* checks a logic expression of the stack and jumps to a relative offset */
HB_P_JUMPTRUE, /* checks a logic expression of the stack and jumps to a relative offset */
HB_P_JUMPFARTRUE, /* checks a logic expression of the stack and jumps to a relative offset */
HB_P_LESSEQUAL, /* checks if the second latest value on the stack is less equal that the latest one, leaves the result only */

View File

@@ -141,7 +141,7 @@ HB_GT_LIBS = \
!if !$d(HB_GT_LIB)
HB_GT_LIB = $(GTWIN_LIB)
!endif
!endif
!endif

View File

@@ -85,7 +85,7 @@ static void AddSearchPath( char * szPath, PATHNAMES * * pSearchList )
the exact date/time info from the resulting ULONG. Since the year
is only stored in 6 bits, 1980 will result in the same bit pattern
as 2044. The purpose of this value is only used to *differenciate*
between the dates ( the exact dates are not significant ), so this
between the dates ( the exact dates are not significant ), so this
can be used here without problems. [vszakats] */
/* 76543210765432107654321076543210
@@ -143,7 +143,7 @@ void hb_compChkCompilerSwitch( int iArg, char * Args[] )
if( HB_ISOPTSEP( * Args[ i ] ) )
hb_compChkEnvironVar( Args[ i ] );
}
}
}
else
/* Chech the environment variables */
{
@@ -247,7 +247,7 @@ void hb_compChkEnvironVar( char * szSwitch )
default:
hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_BADOPTION, s, NULL );
}
}
}
else
hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_BADOPTION, s, NULL );
@@ -268,11 +268,11 @@ void hb_compChkEnvironVar( char * szSwitch )
case '1':
hb_comp_bGenCVerbose = TRUE;
break;
case '0':
hb_comp_bGenCVerbose = FALSE;
break;
default:
hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_BADOPTION, s, NULL );
}
@@ -331,6 +331,20 @@ void hb_compChkEnvironVar( char * szSwitch )
}
break;
case 'j':
case 'J':
switch( *( s + 1 ) )
{
case '0':
hb_comp_iJumpOptimize = 0;
break;
case '1':
hb_comp_iJumpOptimize = 1;
break;
}
break;
case 'l':
case 'L':
hb_comp_bLineNumbers = FALSE;
@@ -476,7 +490,7 @@ void hb_compChkPaths( void )
static void hb_compChkDefineSwitch( char * pszSwitch )
{
if( pszSwitch && HB_ISOPTSEP( pszSwitch[ 0 ] ) &&
if( pszSwitch && HB_ISOPTSEP( pszSwitch[ 0 ] ) &&
( pszSwitch[ 1 ] == 'd' || pszSwitch[ 1 ] == 'D' ) )
{
char * szDefText = hb_strdup( pszSwitch + 2 );
@@ -497,7 +511,7 @@ void hb_compChkDefines( int iArg, char * Args[] )
{
/* Chech the environment variables */
{
/* NOTE: CLIPPERCMD enviroment variable is overriden
/* NOTE: CLIPPERCMD enviroment variable is overriden
if HARBOURCMD exists */
char * szStrEnv = getenv( "HARBOURCMD" );
@@ -521,9 +535,9 @@ void hb_compChkDefines( int iArg, char * Args[] )
{
int i;
/* Check all switches in command line They start with an OS_OPT_DELIMITER
/* Check all switches in command line They start with an OS_OPT_DELIMITER
char */
for( i = 0; i < iArg; i++ )
hb_compChkDefineSwitch( Args[ i ] );
}
}
}

View File

@@ -45,6 +45,7 @@ void hb_compGenCCode( PHB_FNAME pFileName ) /* generates the C language ou
ULONG lPCodePos;
char chr;
BOOL bEndProcRequired;
LONG lOffset;
FILE * yyc; /* file handle for C output */
@@ -355,74 +356,135 @@ void hb_compGenCCode( PHB_FNAME pFileName ) /* generates the C language ou
lPCodePos++;
break;
case HB_P_JUMPSHORT:
/* if( 1 ) ( lPCodePos + 3 ) < pFunc->lPCodePos ) */
{
lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] );
if ( lOffset > 127 )
lOffset -= 256;
fprintf( yyc, "\tHB_P_JUMPSHORT, %i,",
pFunc->pCode[ lPCodePos + 1 ] );
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) );
fprintf( yyc, "\n" );
}
lPCodePos += 2;
break;
case HB_P_JUMP:
/* if( 1 ) ( lPCodePos + 3 ) < pFunc->lPCodePos ) */
{
w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256;
lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 );
if ( lOffset > SHRT_MAX )
lOffset -= 65536;
fprintf( yyc, "\tHB_P_JUMP, %i, %i,",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ] );
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %i (abs: %05li) */", w, lPCodePos + ( w ? w : 3 ) );
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) );
fprintf( yyc, "\n" );
}
lPCodePos += 3;
break;
case HB_P_JUMPFALSE:
w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256;
fprintf( yyc, "\tHB_P_JUMPFALSE, %i, %i,",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ] );
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %i (abs: %05li) */", w, lPCodePos + ( w ? w : 3 ) );
fprintf( yyc, "\n" );
lPCodePos += 3;
break;
case HB_P_JUMPTRUE:
w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256;
fprintf( yyc, "\tHB_P_JUMPTRUE, %i, %i,",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ] );
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %i (abs: %05li) */", w, lPCodePos + ( w ? w : 3 ) );
fprintf( yyc, "\n" );
lPCodePos += 3;
break;
case HB_P_JUMPFAR:
/* if( 1 ) ( lPCodePos + 3 ) < pFunc->lPCodePos ) */
{
LONG lPos = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 + pFunc->pCode[ lPCodePos + 3 ] * 65536;
lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 + pFunc->pCode[ lPCodePos + 3 ] * 65536 );
if ( lOffset > 8388607L )
lOffset -= 16777216;
fprintf( yyc, "\tHB_P_JUMPFAR, %i, %i, %i,",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ],
pFunc->pCode[ lPCodePos + 3 ] );
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %li (abs: %05li) */", lPos, lPCodePos + ( lPos ? lPos : 4 ) );
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) );
fprintf( yyc, "\n" );
}
lPCodePos += 4;
break;
case HB_P_JUMPSHORTFALSE:
lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] );
if ( lOffset > 127 )
lOffset -= 256;
fprintf( yyc, "\tHB_P_JUMPSHORTFALSE, %i,",
pFunc->pCode[ lPCodePos + 1 ] );
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) );
fprintf( yyc, "\n" );
lPCodePos += 2;
break;
case HB_P_JUMPFALSE:
lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 );
if ( lOffset > SHRT_MAX )
lOffset -= 65536;
fprintf( yyc, "\tHB_P_JUMPFALSE, %i, %i,",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ] );
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) );
fprintf( yyc, "\n" );
lPCodePos += 3;
break;
case HB_P_JUMPFARFALSE:
{
LONG lPos = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 + pFunc->pCode[ lPCodePos + 3 ] * 65536;
lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 + pFunc->pCode[ lPCodePos + 3 ] * 65536 );
if ( lOffset > 8388607L )
lOffset -= 16777216;
fprintf( yyc, "\tHB_P_JUMPFARFALSE, %i, %i, %i,",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ],
pFunc->pCode[ lPCodePos + 3 ] );
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %li (abs: %05li) */", lPos, lPCodePos + ( lPos ? lPos : 4 ) );
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) );
fprintf( yyc, "\n" );
}
lPCodePos += 4;
break;
case HB_P_JUMPSHORTTRUE:
lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] );
if ( lOffset > 127 )
lOffset -= 256;
fprintf( yyc, "\tHB_P_JUMPSHORTTRUE, %i,",
pFunc->pCode[ lPCodePos + 1 ] );
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) );
fprintf( yyc, "\n" );
lPCodePos += 2;
break;
case HB_P_JUMPTRUE:
lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 );
if ( lOffset > SHRT_MAX )
lOffset -= 65536;
fprintf( yyc, "\tHB_P_JUMPTRUE, %i, %i,",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ] );
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) );
fprintf( yyc, "\n" );
lPCodePos += 3;
break;
case HB_P_JUMPFARTRUE:
{
LONG lPos = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 + pFunc->pCode[ lPCodePos + 3 ] * 65536;
lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 + pFunc->pCode[ lPCodePos + 3 ] * 65536 );
if ( lOffset > 8388607L )
lOffset -= 16777216;
fprintf( yyc, "\tHB_P_JUMPFARTRUE, %i, %i, %i,",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ],
pFunc->pCode[ lPCodePos + 3 ] );
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %li (abs: %05li) */", lPos, lPCodePos + ( lPos ? lPos : 4 ) );
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %li (abs: %05li) */", lOffset, ( LONG ) ( lPCodePos + lOffset ) );
fprintf( yyc, "\n" );
}
lPCodePos += 4;
@@ -1099,12 +1161,12 @@ void hb_compGenCCode( PHB_FNAME pFileName ) /* generates the C language ou
break;
case HB_P_SEQBEGIN:
w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 + pFunc->pCode[ lPCodePos + 3 ] * 65536;
lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 + pFunc->pCode[ lPCodePos + 3 ] * 65536 );
fprintf( yyc, "\tHB_P_SEQBEGIN, %i, %i, %i,",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ],
pFunc->pCode[ lPCodePos + 3 ] );
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %i (abs: %05li) */", w, lPCodePos + ( w ? w : 4 ) );
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %li (abs: %05li) */", lOffset, lPCodePos + lOffset );
fprintf( yyc, "\n" );
lPCodePos += 4;
break;
@@ -1112,12 +1174,12 @@ void hb_compGenCCode( PHB_FNAME pFileName ) /* generates the C language ou
case HB_P_SEQEND:
if( hb_comp_bGenCVerbose ) fprintf( yyc, "/* %05li */ ", lPCodePos );
else fprintf( yyc, "\t" );
w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 + pFunc->pCode[ lPCodePos + 3 ] * 65536;
lOffset = ( LONG ) ( pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256 + pFunc->pCode[ lPCodePos + 3 ] * 65536 );
fprintf( yyc, "HB_P_SEQEND, %i, %i, %i,",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ],
pFunc->pCode[ lPCodePos + 3 ] );
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %i (abs: %05li) */", w, lPCodePos + ( w ? w : 4 ) );
if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %li (abs: %05li) */", lOffset, lPCodePos + lOffset );
fprintf( yyc, "\n" );
lPCodePos += 4;
break;

View File

@@ -60,6 +60,9 @@ void hb_compFixReturns( void ); /* fixes all last defined function returns jumps
static PFUNCTION hb_compFunctionNew( char *, char ); /* creates and initialises the _FUNC structure */
static void hb_compCheckDuplVars( PVAR pVars, char * szVarName, int iVarScope ); /*checks for duplicate variables definitions */
//int hb_compSort_ULONG( ULONG * ulLeft, ULONG * ulRight );
static void hb_compOptimizeJumps( void );
static void hb_compPrepareOptimize( void );
/* global variables */
FILES hb_comp_files;
@@ -99,6 +102,7 @@ BOOL hb_comp_bCredits = FALSE; /* print credits */
BOOL hb_comp_bLogo = TRUE; /* print logo */
BOOL hb_comp_bSyntaxCheckOnly = FALSE; /* syntax check only */
int hb_comp_iLanguage = LANG_C; /* default Harbour generated output language */
int hb_comp_iJumpOptimize = 1;
typedef struct __EXTERN
{
@@ -671,6 +675,10 @@ static PFUNCTION hb_compFunctionNew( char * szName, HB_SYMBOLSCOPE cScope )
pFunc->iStaticsBase = hb_comp_iStaticCnt;
pFunc->pOwner = NULL;
pFunc->bFlags = 0;
pFunc->iNOOPs = 0;
pFunc->iJumps = 0;
pFunc->pNOOPs = NULL;
pFunc->pJumps = NULL;
return pFunc;
}
@@ -841,6 +849,14 @@ PFUNCTION hb_compFunctionKill( PFUNCTION pFunc )
hb_xfree( ( void * ) pVar );
}
/* Release the NOOP array. */
if ( pFunc->pNOOPs )
hb_xfree( ( void * ) pFunc->pNOOPs );
/* Release the Jumps array. */
if ( pFunc->pJumps )
hb_xfree( ( void * ) pFunc->pJumps );
hb_xfree( ( void * ) pFunc->pCode );
/* hb_xfree( ( void * ) pFunc->szName ); The name will be released in hb_compSymbolKill() */
hb_xfree( ( void * ) pFunc );
@@ -848,7 +864,6 @@ PFUNCTION hb_compFunctionKill( PFUNCTION pFunc )
return pNext;
}
PCOMSYMBOL hb_compSymbolKill( PCOMSYMBOL pSym )
{
PCOMSYMBOL pNext = pSym->pNext;
@@ -1242,20 +1257,86 @@ USHORT hb_compFunctionGetPos( char * szFunctionName ) /* return 0 if not found o
return 0;
}
void hb_compPrepareOptimize()
{
if ( ! hb_comp_iJumpOptimize )
return;
hb_comp_functions.pLast->iJumps++;
//printf( "Preparing for Jump #%i in: %li 3rd Byte=%i", hb_comp_functions.pLast->iJumps, ( ULONG ) ( hb_comp_functions.pLast->lPCodePos - 4 ), hb_comp_functions.pLast->pCode[ hb_comp_functions.pLast->lPCodePos ] );
//getchar();
if ( hb_comp_functions.pLast->pJumps )
{
hb_comp_functions.pLast->pJumps = hb_xrealloc( hb_comp_functions.pLast->pJumps, sizeof( ULONG ) * hb_comp_functions.pLast->iJumps );
hb_comp_functions.pLast->pJumps[ hb_comp_functions.pLast->iJumps - 1 ] = ( ULONG ) ( hb_comp_functions.pLast->lPCodePos - 4 );
}
else
{
hb_comp_functions.pLast->pJumps = hb_xgrab( sizeof( ULONG ) );
hb_comp_functions.pLast->pJumps[ hb_comp_functions.pLast->iJumps - 1 ] = ( LONG ) ( hb_comp_functions.pLast->lPCodePos - 4 );
}
/* Only Reserve Request - Don't know if NOOPs will remain yet. */
if ( hb_comp_functions.pLast->pCode[ hb_comp_functions.pLast->lPCodePos - 3 ] == 0 &&
hb_comp_functions.pLast->pCode[ hb_comp_functions.pLast->lPCodePos - 2 ] == 0 &&
hb_comp_functions.pLast->pCode[ hb_comp_functions.pLast->lPCodePos - 1 ] == 0 )
return;
/* 3rd. Byte might be not used */
if( hb_comp_functions.pLast->pCode[ hb_comp_functions.pLast->lPCodePos - 1 ] == HB_P_NOOP )
{
hb_comp_functions.pLast->iNOOPs++;
if ( hb_comp_functions.pLast->pNOOPs )
{
hb_comp_functions.pLast->pNOOPs = hb_xrealloc( hb_comp_functions.pLast->pNOOPs, sizeof( ULONG ) * hb_comp_functions.pLast->iNOOPs );
hb_comp_functions.pLast->pNOOPs[ hb_comp_functions.pLast->iNOOPs - 1 ] = hb_comp_functions.pLast->lPCodePos - 1;
}
else
{
hb_comp_functions.pLast->pNOOPs = hb_xgrab( sizeof( ULONG ) );
hb_comp_functions.pLast->pNOOPs[ hb_comp_functions.pLast->iNOOPs - 1 ] = hb_comp_functions.pLast->lPCodePos - 1;
}
/* 2nd. Byte might be not used */
if( hb_comp_functions.pLast->pCode[ hb_comp_functions.pLast->lPCodePos - 2 ] == HB_P_NOOP )
{
hb_comp_functions.pLast->iNOOPs++;
if ( hb_comp_functions.pLast->pNOOPs )
{
hb_comp_functions.pLast->pNOOPs = hb_xrealloc( hb_comp_functions.pLast->pNOOPs, sizeof( ULONG ) * hb_comp_functions.pLast->iNOOPs );
hb_comp_functions.pLast->pNOOPs[ hb_comp_functions.pLast->iNOOPs - 1 ] = hb_comp_functions.pLast->lPCodePos - 2;
}
else
{
hb_comp_functions.pLast->pNOOPs = hb_xgrab( sizeof( ULONG ) );
hb_comp_functions.pLast->pNOOPs[ hb_comp_functions.pLast->iNOOPs - 1 ] = hb_comp_functions.pLast->lPCodePos - 2;
}
}
}
}
ULONG hb_compGenJump( LONG lOffset )
{
int iBytes = 3;
/* Just a place holder, it might be a far jump...*/
if ( lOffset == 0 )
{
hb_compGenPCode3( HB_P_JUMPFAR, 0, 0 );
hb_compGenPCode1( 0 );
}
else if ( lOffset >= -128 && lOffset <= 127 )
{
hb_compGenPCode3( HB_P_JUMPSHORT, HB_LOBYTE( lOffset ), HB_P_NOOP );
hb_compGenPCode1( HB_P_NOOP );
}
else if ( lOffset >= SHRT_MIN && lOffset <= SHRT_MAX )
{
hb_compGenPCode3( HB_P_JUMP, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ) );
iBytes = 2;
hb_compGenPCode1( HB_P_NOOP );
}
else if ( lOffset >= (-8388608L) && lOffset <= 8388607L )
{
@@ -1267,23 +1348,28 @@ ULONG hb_compGenJump( LONG lOffset )
hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_JUMP_TOO_LONG, NULL, NULL );
}
return hb_comp_functions.pLast->lPCodePos - iBytes;
hb_compPrepareOptimize();
return hb_comp_functions.pLast->lPCodePos - 3;
}
ULONG hb_compGenJumpFalse( LONG lOffset )
{
int iBytes = 3;
/* Just a place holder, it might be a far jump...*/
if ( lOffset == 0 )
{
hb_compGenPCode3( HB_P_JUMPFARFALSE, 0, 0 );
hb_compGenPCode1( 0 );
}
else if ( lOffset >= -128 && lOffset <= 127 )
{
hb_compGenPCode3( HB_P_JUMPSHORTFALSE, HB_LOBYTE( lOffset ), HB_P_NOOP );
hb_compGenPCode1( HB_P_NOOP );
}
else if ( lOffset >= SHRT_MIN && lOffset <= SHRT_MAX )
{
hb_compGenPCode3( HB_P_JUMPFALSE, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ) );
iBytes = 2;
hb_compGenPCode1( HB_P_NOOP );
}
else if ( lOffset >= (-8388608L) && lOffset <= 8388607L )
{
@@ -1295,102 +1381,28 @@ ULONG hb_compGenJumpFalse( LONG lOffset )
hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_JUMP_TOO_LONG, NULL, NULL );
}
return hb_comp_functions.pLast->lPCodePos - iBytes;
}
hb_compPrepareOptimize();
void hb_compGenJumpThere( ULONG ulFrom, ULONG ulTo )
{
BYTE * pCode = hb_comp_functions.pLast->pCode;
LONG lOffset = ulTo - ulFrom + 1;
if ( lOffset >= SHRT_MIN && lOffset <= SHRT_MAX )
{
switch ( pCode[ ( ULONG ) ulFrom - 1 ] )
{
case HB_P_JUMP :
break;
case HB_P_JUMPTRUE :
break;
case HB_P_JUMPFALSE :
break;
case HB_P_JUMPFAR :
pCode[ ( ULONG ) ulFrom - 1 ] = HB_P_JUMP;
pCode[ ( ULONG ) ulFrom + 2 ] = HB_P_NOOP;
break;
case HB_P_JUMPFARTRUE :
pCode[ ( ULONG ) ulFrom - 1 ] = HB_P_JUMPTRUE;
pCode[ ( ULONG ) ulFrom + 2 ] = HB_P_NOOP;
break;
case HB_P_JUMPFARFALSE :
pCode[ ( ULONG ) ulFrom - 1 ] = HB_P_JUMPFALSE;
pCode[ ( ULONG ) ulFrom + 2 ] = HB_P_NOOP;
break;
case HB_P_SEQBEGIN :
break;
case HB_P_SEQEND :
break;
default:
printf( "\rPCode: %i", pCode[ ( ULONG ) ulFrom - 1 ] );
hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_JUMP_NOT_FOUND, NULL, NULL );
break;
}
pCode[ ( ULONG ) ulFrom ] = HB_LOBYTE( lOffset );
pCode[ ( ULONG ) ulFrom + 1 ] = HB_HIBYTE( lOffset );
}
else if ( lOffset >= (-8388608L) && lOffset <= 8388607L )
{
switch ( pCode[ ( ULONG ) ulFrom - 1 ] )
{
case HB_P_JUMP :
hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_INVALID_JUMP, NULL, NULL );
break;
case HB_P_JUMPTRUE :
hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_INVALID_JUMPTRUE, NULL, NULL );
break;
case HB_P_JUMPFALSE :
hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_INVALID_JUMPFALSE, NULL, NULL );
break;
}
pCode[ ( ULONG ) ulFrom ] = HB_LOBYTE( lOffset );
pCode[ ( ULONG ) ulFrom + 1 ] = HB_HIBYTE( lOffset );
pCode[ ( ULONG ) ulFrom + 2 ] = ( BYTE ) ( ( ( USHORT ) ( lOffset ) >> 16 ) & 0xFF );
}
else
{
hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_JUMP_TOO_LONG, NULL, NULL );
}
}
void hb_compGenJumpHere( ULONG ulOffset )
{
hb_compGenJumpThere( ulOffset, hb_comp_functions.pLast->lPCodePos );
return hb_comp_functions.pLast->lPCodePos - 3;
}
ULONG hb_compGenJumpTrue( LONG lOffset )
{
int iBytes = 3;
/* Just a place holder, it might be a far jump...*/
if ( lOffset == 0 )
{
hb_compGenPCode3( HB_P_JUMPFARTRUE, 0, 0 );
hb_compGenPCode1( 0 );
}
if ( lOffset >= SHRT_MIN && lOffset <= SHRT_MAX )
else if ( lOffset >= -128 && lOffset <= 127 )
{
hb_compGenPCode3( HB_P_JUMPSHORTTRUE, HB_LOBYTE( lOffset ), HB_P_NOOP );
hb_compGenPCode1( HB_P_NOOP );
}
else if ( lOffset >= SHRT_MIN && lOffset <= SHRT_MAX )
{
hb_compGenPCode3( HB_P_JUMPTRUE, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ) );
iBytes = 2;
hb_compGenPCode1( HB_P_NOOP );
}
else if ( lOffset >= (-8388608L) && lOffset <= 8388607L )
{
@@ -1402,7 +1414,218 @@ ULONG hb_compGenJumpTrue( LONG lOffset )
hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_JUMP_TOO_LONG, NULL, NULL );
}
return hb_comp_functions.pLast->lPCodePos - iBytes;
hb_compPrepareOptimize();
return hb_comp_functions.pLast->lPCodePos - 3;
}
void hb_compGenJumpThere( ULONG ulFrom, ULONG ulTo )
{
BYTE * pCode = hb_comp_functions.pLast->pCode;
LONG lOffset = ulTo - ulFrom + 1;
int iOptimize = 1 && hb_comp_iJumpOptimize ;
if ( lOffset >= -128 && lOffset <= 127 )
{
switch ( pCode[ ( ULONG ) ( ulFrom - 1 ) ] )
{
/*
case HB_P_JUMPSHORT :
break;
case HB_P_JUMPSHORTTRUE :
break;
case HB_P_JUMPSHORTFALSE :
break;
case HB_P_JUMP :
pCode[ ( ULONG ) ( ulFrom - 1 ) ] = HB_P_JUMPSHORT;
pCode[ ( ULONG ) ( ulFrom + 1 ) ] = HB_P_NOOP;
pCode[ ( ULONG ) ( ulFrom + 2 ) ] = HB_P_NOOP;
break;
case HB_P_JUMPTRUE :
pCode[ ( ULONG ) ( ulFrom - 1 ) ] = HB_P_JUMPSHORTTRUE;
pCode[ ( ULONG ) ( ulFrom + 1 ) ] = HB_P_NOOP;
pCode[ ( ULONG ) ( ulFrom + 2 ) ] = HB_P_NOOP;
break;
case HB_P_JUMPFALSE :
pCode[ ( ULONG ) ( ulFrom - 1 ) ] = HB_P_JUMPSHORTFALSE;
pCode[ ( ULONG ) ( ulFrom + 1 ) ] = HB_P_NOOP;
pCode[ ( ULONG ) ( ulFrom + 2 ) ] = HB_P_NOOP;
break;
*/
case HB_P_JUMPFAR :
pCode[ ( ULONG ) ( ulFrom - 1 ) ] = HB_P_JUMPSHORT;
pCode[ ( ULONG ) ( ulFrom + 1 ) ] = HB_P_NOOP;
pCode[ ( ULONG ) ( ulFrom + 2 ) ] = HB_P_NOOP;
break;
case HB_P_JUMPFARTRUE :
pCode[ ( ULONG ) ( ulFrom - 1 ) ] = HB_P_JUMPSHORTTRUE;
pCode[ ( ULONG ) ( ulFrom + 1 ) ] = HB_P_NOOP;
pCode[ ( ULONG ) ( ulFrom + 2 ) ] = HB_P_NOOP;
break;
case HB_P_JUMPFARFALSE :
pCode[ ( ULONG ) ( ulFrom - 1 ) ] = HB_P_JUMPSHORTFALSE;
pCode[ ( ULONG ) ( ulFrom + 1 ) ] = HB_P_NOOP;
pCode[ ( ULONG ) ( ulFrom + 2 ) ] = HB_P_NOOP;
break;
case HB_P_SEQBEGIN :
iOptimize = 0;
break;
case HB_P_SEQEND :
iOptimize = 0;
break;
default:
printf( "\rPCode: %i", pCode[ ( ULONG ) ulFrom - 1 ] );
hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_JUMP_NOT_FOUND, NULL, NULL );
break;
}
pCode[ ( ULONG ) ulFrom ] = HB_LOBYTE( lOffset );
if ( ! iOptimize )
return;
/* Check if 3rd. Byte not used. */
if ( pCode[ ( ULONG ) ( ulFrom + 2 ) ] == HB_P_NOOP )
{
hb_comp_functions.pLast->iNOOPs++;
if ( hb_comp_functions.pLast->pNOOPs )
{
hb_comp_functions.pLast->pNOOPs = hb_xrealloc( hb_comp_functions.pLast->pNOOPs, sizeof( ULONG ) * hb_comp_functions.pLast->iNOOPs );
hb_comp_functions.pLast->pNOOPs[ hb_comp_functions.pLast->iNOOPs - 1 ] = ( ULONG ) ulFrom + 2;
}
else
{
hb_comp_functions.pLast->pNOOPs = hb_xgrab( sizeof( ULONG ) );
hb_comp_functions.pLast->pNOOPs[ 0 ] = ( ULONG ) ulFrom + 2;
}
/* Check if 2nd. Byte not used. */
if ( pCode[ ( ULONG ) ulFrom + 1 ] == HB_P_NOOP )
{
hb_comp_functions.pLast->iNOOPs++;
if ( hb_comp_functions.pLast->pNOOPs )
{
hb_comp_functions.pLast->pNOOPs = hb_xrealloc( hb_comp_functions.pLast->pNOOPs, sizeof( ULONG ) * hb_comp_functions.pLast->iNOOPs );
hb_comp_functions.pLast->pNOOPs[ hb_comp_functions.pLast->iNOOPs - 1 ] = ( ULONG ) ulFrom + 1;
}
else
{
hb_comp_functions.pLast->pNOOPs = hb_xgrab( sizeof( ULONG ) );
hb_comp_functions.pLast->pNOOPs[ 0 ] = ( ULONG ) ulFrom + 1;
}
}
}
}
else if ( lOffset >= SHRT_MIN && lOffset <= SHRT_MAX )
{
switch ( pCode[ ( ULONG ) ( ulFrom - 1 ) ] )
{
/*
case HB_P_JUMPSHORT :
pCode[ ( ULONG ) ( ulFrom - 1 ) ] = HB_P_JUMP;
pCode[ ( ULONG ) ( ulFrom + 2 ) ] = HB_P_NOOP;
break;
case HB_P_JUMPSHORTTRUE :
pCode[ ( ULONG ) ( ulFrom - 1 ) ] = HB_P_JUMPTRUE;
pCode[ ( ULONG ) ( ulFrom + 2 ) ] = HB_P_NOOP;
break;
case HB_P_JUMPSHORTFALSE :
pCode[ ( ULONG ) ( ulFrom - 1 ) ] = HB_P_JUMPFALSE;
pCode[ ( ULONG ) ( ulFrom + 2 ) ] = HB_P_NOOP;
break;
case HB_P_JUMP :
break;
case HB_P_JUMPTRUE :
break;
case HB_P_JUMPFALSE :
break;
*/
case HB_P_JUMPFAR :
pCode[ ( ULONG ) ( ulFrom - 1 ) ] = HB_P_JUMP;
pCode[ ( ULONG ) ( ulFrom + 2 ) ] = HB_P_NOOP;
break;
case HB_P_JUMPFARTRUE :
pCode[ ( ULONG ) ( ulFrom - 1 ) ] = HB_P_JUMPTRUE;
pCode[ ( ULONG ) ( ulFrom + 2 ) ] = HB_P_NOOP;
break;
case HB_P_JUMPFARFALSE :
pCode[ ( ULONG ) ( ulFrom - 1 ) ] = HB_P_JUMPFALSE;
pCode[ ( ULONG ) ( ulFrom + 2 ) ] = HB_P_NOOP;
break;
case HB_P_SEQBEGIN :
iOptimize = 0;
break;
case HB_P_SEQEND :
iOptimize = 0;
break;
default:
printf( "\rPCode: %i", pCode[ ( ULONG ) ulFrom - 1 ] );
hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_JUMP_NOT_FOUND, NULL, NULL );
break;
}
pCode[ ulFrom ] = HB_LOBYTE( lOffset );
pCode[ ( ULONG ) ( ulFrom + 1 ) ] = HB_HIBYTE( lOffset );
if ( ! iOptimize )
return;
/* Check if 3rd. Byte not used. */
if ( pCode[ ( ULONG ) ulFrom + 2 ] == HB_P_NOOP )
{
hb_comp_functions.pLast->iNOOPs++;
if ( hb_comp_functions.pLast->pNOOPs )
{
hb_comp_functions.pLast->pNOOPs = hb_xrealloc( hb_comp_functions.pLast->pNOOPs, sizeof( ULONG ) * hb_comp_functions.pLast->iNOOPs );
hb_comp_functions.pLast->pNOOPs[ hb_comp_functions.pLast->iNOOPs - 1 ] = ( ULONG ) ulFrom + 2;
}
else
{
hb_comp_functions.pLast->pNOOPs = hb_xgrab( sizeof( ULONG ) );
hb_comp_functions.pLast->pNOOPs[ 0 ] = ( ULONG ) ulFrom + 2;
}
}
}
else if ( lOffset >= (-8388608L) && lOffset <= 8388607L )
{
pCode[ ulFrom ] = HB_LOBYTE( lOffset );
pCode[ ( ULONG ) ( ulFrom + 1 ) ] = HB_HIBYTE( lOffset );
pCode[ ( ULONG ) ( ulFrom + 2 ) ] = ( BYTE ) ( ( ( USHORT ) ( lOffset ) >> 16 ) & 0xFF );
}
else
{
hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_JUMP_TOO_LONG, NULL, NULL );
}
}
void hb_compGenJumpHere( ULONG ulOffset )
{
hb_compGenJumpThere( ulOffset, hb_comp_functions.pLast->lPCodePos );
}
void hb_compLinePush( void ) /* generates the pcode with the currently compiled source code line */
@@ -1446,7 +1669,6 @@ void hb_compLinePushIfDebugger( void )
}
hb_comp_functions.pLast->bFlags &= ~ ( FUN_WITH_RETURN | FUN_BREAK_CODE ); /* clear RETURN flag */
}
}
void hb_compLinePushIfInside( void ) /* generates the pcode with the currently compiled source code line */
@@ -2062,6 +2284,10 @@ static void hb_compCheckDuplVars( PVAR pVar, char * szVarName, int iVarScope )
void hb_compFixReturns( void ) /* fixes all last defined function returns jumps offsets */
{
if ( hb_comp_iJumpOptimize )
if ( hb_comp_functions.pLast && hb_comp_functions.pLast->iNOOPs )
hb_compOptimizeJumps();
if( hb_comp_iWarnings && hb_comp_functions.pLast )
{
PVAR pVar;
@@ -2093,6 +2319,250 @@ void hb_compFixReturns( void ) /* fixes all last defined function returns jumps
}
}
int hb_compSort_ULONG( const void * pLeft, const void * pRight )
{
ULONG ulLeft = *( (ULONG *) (pLeft) );
ULONG ulRight = *( (ULONG *) (pRight) );
if ( ulLeft == ulRight )
return 0 ;
else if ( ulLeft < ulRight )
return -1;
else
return 1;
}
void hb_compOptimizeJumps( void )
{
/* Jump Optimizer */
BYTE * pCode = hb_comp_functions.pLast->pCode;
BYTE * pOptimized = hb_xgrab( hb_comp_functions.pLast->lPCodePos - hb_comp_functions.pLast->iNOOPs );
ULONG * pNOOPs = hb_comp_functions.pLast->pNOOPs;
ULONG * pJumps = hb_comp_functions.pLast->pJumps;
int * piShifts = hb_xgrab( sizeof( int ) * hb_comp_functions.pLast->iJumps );
ULONG ulOptimized = 0;
ULONG ulNextByte = 0;
int iNOOP;
ULONG ulOffset;
ULONG ulBytes2Copy;
int iJump;
int iForward;
//printf( "\rOptimize ON" );
//getchar();
/* Needed so the pasting of PCODE pieces below will work correctly */
qsort( (void *) pNOOPs, hb_comp_functions.pLast->iNOOPs, sizeof( ULONG ), hb_compSort_ULONG );
/*
for( iNOOP = 0; iNOOP < hb_comp_functions.pLast->iNOOPs; iNOOP++ )
{
printf( "\rNOOP #%i at:%li", iNOOP, pNOOPs[ iNOOP ] );
getchar();
if ( pNOOPs[ iNOOP ] == 0 )
{
printf( "\r*** 0 *** NOOP # %i at:%li", iNOOP, pNOOPs[ iNOOP ] );
getchar();
}
}
for( iJump = 0; iJump < hb_comp_functions.pLast->iJumps; iJump++ )
{
switch ( pCode[ pJumps[ iJump ] ] )
{
case HB_P_JUMPSHORT :
case HB_P_JUMPSHORTFALSE :
case HB_P_JUMPSHORTTRUE :
{
ulOffset = pCode[ pJumps[ iJump ] + 1 ];
if ( ulOffset > 127 )
{
ulOffset -= 256;
iForward = 0;
}
else
iForward = 1;
}
break;
case HB_P_JUMP :
case HB_P_JUMPFALSE :
case HB_P_JUMPTRUE :
{
ulOffset = ( ULONG ) ( pCode[ pJumps[ iJump ] + 1 ] + ( pCode[ pJumps[ iJump ] + 2 ] * 256 ) );
if ( ulOffset > SHRT_MAX )
{
ulOffset -= 65536;
iForward = 0;
}
else
iForward = 1;
}
break;
default:
{
ulOffset = ( ULONG )( pCode[ pJumps[ iJump ] + 1 ] + ( pCode[ pJumps[ iJump ] + 2 ] * 256 ) + ( pCode[ pJumps[ iJump ] + 3 ] * 65536 ) );
if ( ulOffset > 8388607L )
{
ulOffset -= 16777216L;
iForward = 0;
}
}
break;
}
printf( "\rJump=%li, Base=%li, Offset=%li, Target=%li", iJump, pJumps[ iJump ], ulOffset, pJumps[ iJump ] + ulOffset );
getchar();
if ( pJumps[ iJump ] == 0 || ulOffset == 0 )
{
printf( "\r*** 0 *** Jump=%li, Base=%li, Offset=%li, Target=%li", iJump, pJumps[ iJump ], ulOffset, pJumps[ iJump ] + ulOffset );
getchar();
}
}
*/
for( iJump = 0; iJump < hb_comp_functions.pLast->iJumps; iJump++ )
piShifts[ iJump ] = 0;
/* First Scan NOOPS - Adjust Jump addresses. */
for( iNOOP = 0; iNOOP < hb_comp_functions.pLast->iNOOPs; iNOOP++ )
{
/* Adjusting preceding jumps that pooint to code beyond the current NOOP or trailing backward jumps pointing to lower address. */
for ( iJump = 0; iJump < hb_comp_functions.pLast->iJumps ; iJump++ )
{
switch ( pCode[ pJumps[ iJump ] ] )
{
case HB_P_JUMPSHORT :
case HB_P_JUMPSHORTFALSE :
case HB_P_JUMPSHORTTRUE :
{
ulOffset = pCode[ pJumps[ iJump ] + 1 ];
if ( ulOffset > 127 )
{
ulOffset -= 256;
iForward = 0;
}
else
iForward = 1;
}
break;
case HB_P_JUMP :
case HB_P_JUMPFALSE :
case HB_P_JUMPTRUE :
{
ulOffset = ( ULONG ) ( pCode[ pJumps[ iJump ] + 1 ] + ( pCode[ pJumps[ iJump ] + 2 ] * 256 ) );
if ( ulOffset > SHRT_MAX )
{
ulOffset -= 65536;
iForward = 0;
}
else
iForward = 1;
}
break;
default:
{
ulOffset = ( ULONG )( pCode[ pJumps[ iJump ] + 1 ] + ( pCode[ pJumps[ iJump ] + 2 ] * 256 ) + ( pCode[ pJumps[ iJump ] + 3 ] * 65536 ) );
if ( ulOffset > 8388607L )
{
ulOffset -= 16777216L;
iForward = 0;
}
}
break;
}
/* Only intrested in forward (positive) jumps. */
if ( iForward )
{
//printf( "\rCurrent NOOP=%li, Address=%li, Jump=%i, Base=%li, Offset=%li, Target=%li", iNOOP, pNOOPs[ iNOOP ], iJump, pJumps[ iJump ], ulOffset, pJumps[ iJump ] + ulOffset );
//getchar();
/* Only if points to code beyond the current fix. */
if ( pJumps[ iJump ] < pNOOPs[ iNOOP ] && pJumps[ iJump ] + piShifts[ iJump ] + ulOffset > pNOOPs[ iNOOP ] )
{
/* Increasing Shift Counter for this Jump. */
piShifts[ iJump ]++;
if ( pCode[ pJumps[ iJump ] + 1 ] )
pCode[ pJumps[ iJump ] + 1 ]--;
else
{
pCode[ pJumps[ iJump ] + 1 ] = 255;
pCode[ pJumps[ iJump ] + 2 ]--;
}
//printf( "\rAdjusted Jump=%li To: %li", iJump, ( pCode[ pJumps[ iJump ] + 1 ] + pCode[ pJumps[ iJump ] + 2 ] * 256 ) );
//getchar();
}
}
else
{
/* Adjusting all later jumps (if negative) and target prior the current NOOP. */
//printf( "\rCurrent NOOP=%li, Address=%li, Jump=%i, Base=%li, Offset=%li, Target=%li", iNOOP, pNOOPs[ iNOOP ], iJump, pJumps[ iJump ], ulOffset, pJumps[ iJump ] + ulOffset );
//getchar();
// Only if points to code beyond the current fix.
if ( pJumps[ iJump ] > pNOOPs[ iNOOP ] && pJumps[ iJump ] + piShifts[ iJump ] + ulOffset < pNOOPs[ iNOOP ] )
{
/* Decreasing Shift Counter for this Jump. */
piShifts[ iJump ]--;
if ( pCode[ pJumps[ iJump ] + 1 ] < 255 )
pCode[ pJumps[ iJump ] + 1 ]++;
else
{
pCode[ pJumps[ iJump ] + 1 ] = 0;
pCode[ pJumps[ iJump ] + 2 ]++;
}
//printf( "\rAdjusted Jump=%li To: %li", iJump, ( pCode[ pJumps[ iJump ] + 1 ] + pCode[ pJumps[ iJump ] + 2 ] * 256 - 65536 ) );
//getchar();
}
}
}
}
//printf( "\rPasting" );
//getchar();
/* Second Scan, after all adjustements been made, we can copy the optimized code. */
for( iNOOP = 0; iNOOP < hb_comp_functions.pLast->iNOOPs; iNOOP++ )
{
ulBytes2Copy = ( pNOOPs[ iNOOP ] - ulNextByte ) ;
while ( ulBytes2Copy-- > 0 )
pOptimized[ ulOptimized++ ] = pCode[ ulNextByte++ ];
/* Skip the NOOP and point to next valid byte */
ulNextByte++;
}
//printf( "\rCopying Remainder" );
//getchar();
/* Copy remainder beyond the last NOOP. */
while ( ulNextByte < hb_comp_functions.pLast->lPCodePos )
pOptimized[ ulOptimized++ ] = pCode[ ulNextByte++ ];
//printf( "\rCopied" );
//getchar();
hb_xfree( (void *) pCode );
hb_comp_functions.pLast->pCode = pOptimized;
hb_comp_functions.pLast->lPCodePos = ulOptimized;
hb_comp_functions.pLast->lPCodeSize = ulOptimized;
}
/* Generate the opcode to open BEGIN/END sequence
* This code is simmilar to JUMP opcode - the offset will be filled with
* - either the address of HB_P_SEQEND opcode if there is no RECOVER clause
@@ -2103,6 +2573,8 @@ ULONG hb_compSequenceBegin( void )
hb_compGenPCode3( HB_P_SEQBEGIN, 0, 0 );
hb_compGenPCode1( 0 );
hb_compPrepareOptimize();
return hb_comp_functions.pLast->lPCodePos - 3;
}
@@ -2118,6 +2590,8 @@ ULONG hb_compSequenceEnd( void )
hb_compGenPCode3( HB_P_SEQEND, 0, 0 );
hb_compGenPCode1( 0 );
hb_compPrepareOptimize();
return hb_comp_functions.pLast->lPCodePos - 3;
}

View File

@@ -82,10 +82,7 @@ char * hb_comp_szErrors[] =
"Macro of declared symbol: \'%s\'",
"Invalid selector in send: \'%s\'",
"ANNOUNCEd procedure \'%s\' must be a public symbol",
"Jump offset too long for HB_P_JUMP needed HB_P_JUMPFAR",
"Jump offset too long for HB_P_JUMPTRUE needed HB_P_JUMPFARTRUE",
"Jump offset too long for HB_P_JUMPFALSE needed HB_P_JUMPFARFALSE",
"HB_P_JUMPx not found when fixing offset"
"Jump PCode not found",
};
/* Table with parse warnings */

View File

@@ -362,10 +362,11 @@ void hb_vmQuit( void )
void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols )
{
BYTE bCode;
USHORT w = 0;
LONG w = 0;
USHORT uiParams;
BOOL bCanRecover = FALSE;
ULONG ulPrivateBase;
LONG lOffset;
HB_TRACE(HB_TR_DEBUG, ("hb_vmExecute(%p, %p)", pCode, pSymbols));
@@ -623,7 +624,12 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols )
* 2) store the address of RECOVER or END opcode
*/
hb_stack.pPos->type = HB_IT_LONG;
hb_stack.pPos->item.asLong.value = w + pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + ( pCode[ w + 3 ] * 65536 );
lOffset = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + ( pCode[ w + 3 ] * 65536 );
if ( lOffset > 8388607L )
lOffset = ( lOffset - 16777216 );
hb_stack.pPos->item.asLong.value = w + lOffset;
hb_stackPush();
/*
* 3) store current RECOVER base
@@ -679,7 +685,11 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols )
/*
* skip outside of SEQUENCE structure
*/
w += pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + ( pCode[ w + 3 ] * 65536 );
lOffset = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + ( pCode[ w + 3 ] * 65536 );
if ( lOffset > 8388607L )
lOffset = ( lOffset - 16777216 );
w += lOffset;
break;
case HB_P_SEQRECOVER:
@@ -712,46 +722,123 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols )
/* Jumps */
case HB_P_JUMPSHORT:
lOffset = pCode[ w + 1 ];
if ( lOffset > 127 )
lOffset -= 256 ;
/*
if( lOffset )
w += lOffset;
else
w += 2;
*/
w += lOffset;
break;
case HB_P_JUMP:
uiParams = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 );
if( uiParams )
w += uiParams;
lOffset = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 );
if ( lOffset > SHRT_MAX )
lOffset -= 65536;
/*
if( lOffset )
w += lOffset;
else
w += 3;
*/
w += lOffset;
break;
case HB_P_JUMPFAR:
uiParams = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + ( pCode[ w + 3 ] * 65536 );
if( uiParams )
w += uiParams;
lOffset = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + ( pCode[ w + 3 ] * 65536 );
if ( lOffset > 8388607L )
lOffset -= 16777216L;
/*
if( lOffset )
w += lOffset;
else
w += 4;
*/
w += lOffset;
break;
case HB_P_JUMPSHORTFALSE:
if( ! hb_vmPopLogical() )
{
lOffset = pCode[ w + 1 ];
if ( lOffset > 127 )
lOffset -= 256;
w += lOffset;
}
else
w += 2;
break;
case HB_P_JUMPFALSE:
if( ! hb_vmPopLogical() )
w += pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 );
{
lOffset = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 );
if ( lOffset > SHRT_MAX )
lOffset -= 65536;
w += lOffset;
}
else
w += 3;
break;
case HB_P_JUMPFARFALSE:
if( ! hb_vmPopLogical() )
w += pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + ( pCode[ w + 3 ] * 65536 );
{
lOffset = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + ( pCode[ w + 3 ] * 65536 );
if ( lOffset > 8388607L )
lOffset -= 16777216L;
w += lOffset;
}
else
w += 4;
break;
case HB_P_JUMPSHORTTRUE:
if( hb_vmPopLogical() )
{
lOffset = pCode[ w + 1 ];
if ( lOffset > 127 )
lOffset -= 256;
w += lOffset;
}
else
w += 2;
break;
case HB_P_JUMPTRUE:
if( hb_vmPopLogical() )
w += pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 );
{
lOffset = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 );
if ( lOffset > SHRT_MAX )
lOffset -= 65536;
w += lOffset;
}
else
w += 3;
break;
case HB_P_JUMPFARTRUE:
if( hb_vmPopLogical() )
w += pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + ( pCode[ w + 3 ] * 65536 );
{
lOffset = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) + ( pCode[ w + 3 ] * 65536 );
if ( lOffset > 8388607L )
lOffset -= 16777216L;
w += lOffset;
}
else
w += 4;
break;

View File

@@ -1,19 +1,26 @@
//
// $Id$
//
#include "setcurs.ch"
//
#define ALTD_DISABLE 0
#define ALTD_ENABLE 1
procedure main()
static s_oDebugger
static s_lExit := .F.
local s := " " + chr(0) + " mab " + chr(0) + " "
function AltD( nAction )
static s_lEnabled := .t.
StrDump( s )
QOut( s )
do case
case nAction == nil
if s_lEnabled
s_lExit := .f.
__dbgEntry( ProcLine( 2 ) )
endif
qout( '"' + ltrim(s) + '"' )
qout( '"' + rtrim(s) + '"' )
qout( '"' + alltrim(s) + '"' )
case nAction == ALTD_DISABLE
s_lEnabled := .f.
return
case nAction == ALTD_ENABLE
s_lEnabled := .t.
endcase
return nil