2006-12-15 16:55 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)

* harbour/include/hbapi.h
  * harbour/include/hbcomp.h
  * harbour/include/hbcompdf.h
  * harbour/include/hbdefs.h
  * harbour/include/hberrors.h
  * harbour/include/hbexpra.c
  * harbour/include/hbexprb.c
  * harbour/include/hbexprc.c
  * harbour/include/hbpcode.h
  * harbour/include/hbxvm.h
  * harbour/source/common/expropt1.c
  * harbour/source/common/expropt2.c
  * harbour/source/common/hbstr.c
  * harbour/source/compiler/cmdcheck.c
  * harbour/source/compiler/genc.c
  * harbour/source/compiler/gencc.c
  * harbour/source/compiler/gencobj.c
  * harbour/source/compiler/harbour.c
  * harbour/source/compiler/harbour.y
  * harbour/source/compiler/harbour.yyc
  * harbour/source/compiler/hbdead.c
  * harbour/source/compiler/hbfix.c
  * harbour/source/compiler/hbgenerr.c
  * harbour/source/compiler/hblbl.c
  * harbour/source/compiler/hbpcode.c
  * harbour/source/compiler/hbstripl.c
  * harbour/source/macro/macro.y
  * harbour/source/macro/macro.yyc
  * harbour/source/rtl/console.c
  * harbour/source/rtl/isprint.c
  * harbour/source/rtl/left.c
  * harbour/source/rtl/right.c
  * harbour/source/rtl/strtran.c
  * harbour/source/vm/codebloc.c
  * harbour/source/vm/hvm.c
  * harbour/source/vm/macro.c
    * general PCODE cleanup and address most of TODO/TOFIX notes in
      source code:
      ! fixed GPF traps when too long string or codeblock is generatd
      + added support for 16MB codeblocks and strings
      ! removed macrocompiler limitation for jumps range
      ! fixed GPF when more then 255 local variables is used and added
        support for 2^15 locals
      ! removed all strtok() functions
      % added optimization for all +=, -=, *=, %=, ^=, **= operations
        when left side of expression is variable or array item
      % added optimization for all +=, -=, *=, %=, ^=, **= operations
        when left side of expression is object method and updated ++, --
        for new code. It's still disabled until we will not add support
        for late evaluated reference items to HVM
      ! fixed a[++i]++ and similar operations (a[++i]*=2, ...). Now ++i is
        executed only once. It's not Clipper compatible but it was in
        TODO note in source code. It can be disabled by -kc option
      * finished support to xHarbour like #pragma TEXTHIDDEN(1)
      ! fixed local add int optimization when PARAMETERS used after
        optimization changed local variable number over 255
      ! fixed GPF trap when in HB_P_<op>EQ PCODEs when executed for
        direct values
      * others
    ! fixed problems reported by Chen
    * optimized strtran(), left(), right() to not create new string copy
      when the same value is returned
This commit is contained in:
Przemyslaw Czerpak
2006-12-15 15:54:28 +00:00
parent 22159d57b5
commit bdb38dde43
39 changed files with 2275 additions and 1411 deletions

View File

@@ -8,6 +8,70 @@
2002-12-01 13:30 UTC+0100 Foo Bar <foo.bar@foobar.org>
*/
2006-12-15 16:55 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbapi.h
* harbour/include/hbcomp.h
* harbour/include/hbcompdf.h
* harbour/include/hbdefs.h
* harbour/include/hberrors.h
* harbour/include/hbexpra.c
* harbour/include/hbexprb.c
* harbour/include/hbexprc.c
* harbour/include/hbpcode.h
* harbour/include/hbxvm.h
* harbour/source/common/expropt1.c
* harbour/source/common/expropt2.c
* harbour/source/common/hbstr.c
* harbour/source/compiler/cmdcheck.c
* harbour/source/compiler/genc.c
* harbour/source/compiler/gencc.c
* harbour/source/compiler/gencobj.c
* harbour/source/compiler/harbour.c
* harbour/source/compiler/harbour.y
* harbour/source/compiler/harbour.yyc
* harbour/source/compiler/hbdead.c
* harbour/source/compiler/hbfix.c
* harbour/source/compiler/hbgenerr.c
* harbour/source/compiler/hblbl.c
* harbour/source/compiler/hbpcode.c
* harbour/source/compiler/hbstripl.c
* harbour/source/macro/macro.y
* harbour/source/macro/macro.yyc
* harbour/source/rtl/console.c
* harbour/source/rtl/isprint.c
* harbour/source/rtl/left.c
* harbour/source/rtl/right.c
* harbour/source/rtl/strtran.c
* harbour/source/vm/codebloc.c
* harbour/source/vm/hvm.c
* harbour/source/vm/macro.c
* general PCODE cleanup and address most of TODO/TOFIX notes in
source code:
! fixed GPF traps when too long string or codeblock is generatd
+ added support for 16MB codeblocks and strings
! removed macrocompiler limitation for jumps range
! fixed GPF when more then 255 local variables is used and added
support for 2^15 locals
! removed all strtok() functions
% added optimization for all +=, -=, *=, %=, ^=, **= operations
when left side of expression is variable or array item
% added optimization for all +=, -=, *=, %=, ^=, **= operations
when left side of expression is object method and updated ++, --
for new code. It's still disabled until we will not add support
for late evaluated reference items to HVM
! fixed a[++i]++ and similar operations (a[++i]*=2, ...). Now ++i is
executed only once. It's not Clipper compatible but it was in
TODO note in source code. It can be disabled by -kc option
* finished support to xHarbour like #pragma TEXTHIDDEN(1)
! fixed local add int optimization when PARAMETERS used after
optimization changed local variable number over 255
! fixed GPF trap when in HB_P_<op>EQ PCODEs when executed for
direct values
* others
! fixed problems reported by Chen
* optimized strtran(), left(), right() to not create new string copy
when the same value is returned
2006-12-13 18:45 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/source/rtl/console.c
* pacify false CG error messages - Chen Kedem modifications (sizeof(int)

View File

@@ -857,7 +857,7 @@ static ULONG BranchGet( struct hb_BTree * pBTree, ULONG ulNode, int iPosition )
return pBTree->ioBuffer->pulBranch[ iPosition ];
}
#ifdef DEBUG
#if defined( DEBUG )
static void Chk4Loop( struct hb_BTree * pBTree, ULONG ulNode, int iPosition, ULONG ulBranch )
{
/*

View File

@@ -730,8 +730,8 @@ extern HB_EXPORT BOOL hb_winmainArgGet( HANDLE * phInstance, HANDLE * phPrevInst
/* Codeblock management */
extern HB_EXPORT void * hb_codeblockId( PHB_ITEM pItem ); /* retrieves the codeblock unique ID */
extern HB_CODEBLOCK_PTR hb_codeblockNew( const BYTE * pBuffer, USHORT uiLocals, const BYTE * pLocalPosTable, PHB_SYMB pSymbols, USHORT usLen ); /* create a code-block */
extern HB_CODEBLOCK_PTR hb_codeblockMacroNew( BYTE * pBuffer, USHORT usLen );
extern HB_CODEBLOCK_PTR hb_codeblockNew( const BYTE * pBuffer, USHORT uiLocals, const BYTE * pLocalPosTable, PHB_SYMB pSymbols, ULONG ulLen ); /* create a code-block */
extern HB_CODEBLOCK_PTR hb_codeblockMacroNew( BYTE * pBuffer, ULONG ulLen );
extern PHB_ITEM hb_codeblockGetVar( PHB_ITEM pItem, LONG iItemPos ); /* get local variable referenced in a codeblock */
extern PHB_ITEM hb_codeblockGetRef( HB_CODEBLOCK_PTR pCBlock, LONG iItemPos ); /* get local variable passed by reference */
extern void hb_codeblockEvaluate( HB_ITEM_PTR pItem ); /* evaluate a codeblock */
@@ -770,6 +770,8 @@ extern void hb_conXSaveRestRelease( void ); /* release the save/restore API
/* compiler and macro compiler */
extern char * hb_compReservedName( char * szName ); /* determines if a string contains a reserve word */
extern char * hb_compEncodeString( int iMethod, const char * szText, ULONG * pulLen );
extern char * hb_compDecodeString( int iMethod, const char * szText, ULONG * pulLen );
/* misc */
extern char * hb_procname( int iLevel, char * szName, BOOL bskipBlock ); /* retrieve a procedure name into a buffer */

View File

@@ -312,7 +312,7 @@ extern void hb_compGenObj32( HB_COMP_DECL, PHB_FNAME ); /* generates OBJ 32
extern void hb_compGenCObj( HB_COMP_DECL, PHB_FNAME ); /* generates platform dependant object module */
extern void hb_compGenCRealCode( HB_COMP_DECL, PFUNCTION pFunc, FILE * yyc );
extern void hb_compGenCString( FILE * yyc, BYTE * pText, USHORT usLen );
extern void hb_compGenCString( FILE * yyc, BYTE * pText, ULONG ulLen );
/* hbident.c */
extern char * hb_compIdentifierNew( HB_COMP_DECL, char * szName, int iType ); /* create the reusable identifier */

View File

@@ -364,6 +364,7 @@ typedef struct HB_EXPR_
{
struct HB_EXPR_ *pExprList; /* list elements */
struct HB_EXPR_ *pIndex; /* array index, others */
BOOL reference; /* push array item by reference */
} asList;
struct
{

View File

@@ -313,6 +313,19 @@
# endif
#endif
#if !defined( UCHAR_MAX )
# define UCHAR_MAX 0x0FF
#endif
#if !defined( UINT24_MAX )
# define UINT24_MAX 0x0FFFFFFL
#endif
#if !defined( INT24_MAX )
# define INT24_MAX 8388607L
#endif
#if !defined( INT24_MIN )
# define INT24_MIN -8388608L
#endif
#if defined( HB_ARCH_64BIT ) && !defined( _WIN64 )
# if !defined( UINT64 )
typedef ULONG UINT64;
@@ -388,12 +401,12 @@
#define HB_DBL_LIM_INT8(d) ( -128 <= (d) && (d) <= 127 )
#define HB_DBL_LIM_INT16(d) ( INT16_MIN <= (d) && (d) <= INT16_MAX )
#define HB_DBL_LIM_INT24(d) ( -8388608.0 <= (d) && (d) <= 8388607.0 )
#define HB_DBL_LIM_INT24(d) ( INT24_MIN <= (d) && (d) <= INT24_MAX )
#define HB_DBL_LIM_INT32(d) ( INT32_MIN <= (d) && (d) <= INT32_MAX )
#define HB_DBL_LIM_INT64(d) ( (HB_MAXDBL) INT64_MIN <= (HB_MAXDBL) (d) && (HB_MAXDBL) (d) <= (HB_MAXDBL) INT64_MAX )
#define HB_LIM_INT8(l) ( -128 <= (l) && (l) <= 127 )
#define HB_LIM_INT16(l) ( INT16_MIN <= (l) && (l) <= INT16_MAX )
#define HB_LIM_INT24(l) ( -8388608L <= (l) && (l) <= 8388607L )
#define HB_LIM_INT24(l) ( INT24_MIN <= (l) && (l) <= INT24_MAX )
#define HB_LIM_INT32(l) ( INT32_MIN <= (l) && (l) <= INT32_MAX )
#define HB_LIM_INT64(l) ( INT64_MIN <= (l) && (l) <= INT64_MAX )
@@ -543,7 +556,9 @@ typedef unsigned long HB_COUNTER;
#define HB_MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
#define HB_LOBYTE( w ) ( ( BYTE ) ( w ) )
#define HB_HIBYTE( w ) ( ( BYTE ) ( ( ( w ) >> 8 ) & 0xFF ) )
#define HB_HIBYTE( w ) ( ( BYTE ) ( ( ( w ) >> 8 ) & 0xFF ) )
#define HB_ULBYTE( w ) ( ( BYTE ) ( ( ( w ) >> 16 ) & 0xFF ) )
#define HB_UHBYTE( w ) ( ( BYTE ) ( ( ( w ) >> 24 ) & 0xFF ) )
#define HB_LOWORD( l ) ( ( UINT16 ) ( l ) )
#define HB_HIWORD( l ) ( ( UINT16 ) ( ( ( l ) >> 16 ) & 0xFFFF ) )
#define HB_MKSHORT( lo, hi ) ( ( SHORT ) ( ( ( INT16 ) ( hi ) ) << 8 ) | ( lo ) )
@@ -898,7 +913,7 @@ typedef unsigned long HB_COUNTER;
# endif
#define HB_USHORT_FROM_LE( w ) HB_MKUSHORT( HB_HIBYTE( w ), HB_LOBYTE( w ) )
#define HB_ULONG_FROM_LE( l ) HB_MKULONG( HB_HIBYTE( HB_HIWORD( l ) ), HB_LOBYTE( HB_HIWORD( l ) ), HB_HIBYTE( l ), HB_LOBYTE( l ) )
#define HB_ULONG_FROM_LE( l ) HB_MKULONG( HB_UHBYTE( l ), HB_ULBYTE( l ), HB_HIBYTE( l ), HB_LOBYTE( l ) )
#define HB_USHORT_TO_LE( w ) HB_USHORT_FROM_LE( w )
#define HB_ULONG_TO_LE( l ) HB_ULONG_FROM_LE( l )

View File

@@ -122,6 +122,9 @@ HB_EXTERN_BEGIN
#define HB_COMP_ERR_WITHOBJECT 60
#define HB_COMP_ERR_BUFFER_OVERFLOW 61
#define HB_COMP_ERR_UNSUPPORTED_LANG 62
#define HB_COMP_ERR_STRING_TOO_LONG 63
#define HB_COMP_ERR_BLOCK_TOO_BIG 64
#define HB_COMP_ERR_OPEN_CFG 65
#define HB_COMP_WARN_AMBIGUOUS_VAR 1
#define HB_COMP_WARN_MEMVAR_ASSUMED 2

View File

@@ -50,15 +50,6 @@
*
*/
/* TOFIX: Split the code, since MSC8 can't compile it, even in Huge model. */
/* TODO:
* - Correct post- and pre- operations to correctly handle the following code
* a[ i++ ]++
* Notice: in current implementation (an in Clipper too) 'i++' is evaluated
* two times! This causes that the new value (after incrementation) is
* stored in next element of the array.
*/
#include <math.h>
#include "hbcomp.h"
@@ -666,8 +657,8 @@ HB_EXPR_PTR hb_compExprNewSend( HB_EXPR_PTR pObject, char * szMessage,
HB_TRACE(HB_TR_DEBUG, ("hb_compExprNewSend(%p,%s,%p,%p)", pObject, szMessage, pMessage, HB_COMP_PARAM));
pExpr = hb_compExprNew( HB_ET_SEND, HB_COMP_PARAM );
pExpr->value.asMessage.pObject = pObject;
pExpr->value.asMessage.pParms = NULL;
pExpr->value.asMessage.pObject = pObject;
pExpr->value.asMessage.pParms = NULL;
if( szMessage != NULL )
{
@@ -789,6 +780,7 @@ HB_EXPR_PTR hb_compExprNewArrayAt( HB_EXPR_PTR pArray, HB_EXPR_PTR pIndex, HB_CO
HB_EXPR_USE( pIndex, HB_EA_ARRAY_INDEX );
pExpr->value.asList.pExprList = pArray;
pExpr->value.asList.pIndex = pIndex;
pExpr->value.asList.reference = FALSE;
return pExpr;
}

View File

@@ -50,16 +50,6 @@
*
*/
/* TOFIX: Split the code, since MSC8 can't compile it, even in Huge model. */
/* TODO:
* - Correct post- and pre- operations to correctly handle the following code
* a[ i++ ]++
* Notice: in current implementation (an in Clipper too) 'i++' is evaluated
* two times! This causes that the new value (after incrementation) is
* stored in next element of the array.
*/
#include <math.h>
#include "hbcomp.h"
#include "hbmacro.ch"
@@ -1302,8 +1292,10 @@ static HB_EXPR_FUNC( hb_compExprUseArrayAt )
}
}
HB_EXPR_USE( pSelf->value.asList.pIndex, HB_EA_PUSH_PCODE );
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_ARRAYPUSH );
if( pSelf->value.asList.reference )
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_ARRAYPUSHREF );
else
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_ARRAYPUSH );
}
break;
@@ -1402,7 +1394,7 @@ static HB_EXPR_FUNC( hb_compExprUseMacro )
hb_compErrorMacro( HB_COMP_PARAM, pSelf->value.asMacro.szMacro );
}
#endif
HB_EXPR_PCODE2( hb_compGenPushString, pSelf->value.asMacro.szMacro, strlen(pSelf->value.asMacro.szMacro) + 1 );
HB_EXPR_PCODE2( hb_compGenPushString, pSelf->value.asMacro.szMacro, strlen( pSelf->value.asMacro.szMacro ) + 1 );
}
}
/* compile & run - leave a result on the eval stack
@@ -1415,7 +1407,7 @@ static HB_EXPR_FUNC( hb_compExprUseMacro )
else if( pSelf->value.asMacro.SubType != HB_ET_MACRO_ALIASED )
{
if( HB_COMP_ISSUPPORTED(HB_COMPFLAG_XBASE) )
if( HB_SUPPORT_XBASE )
{
if( pSelf->value.asMacro.SubType & HB_ET_MACRO_LIST )
{
@@ -1563,18 +1555,18 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall )
}
else if( ( strcmp( "LEN", pName->value.asSymbol ) == 0 ) && usCount )
{
if( HB_COMP_ISSUPPORTED(HB_COMPFLAG_HARBOUR) )
if( HB_SUPPORT_HARBOUR )
hb_compExprReduceLEN( pSelf, HB_COMP_PARAM );
}
else if( ( strcmp( "ASC", pName->value.asSymbol ) == 0 ) && usCount )
{
if( HB_COMP_ISSUPPORTED(HB_COMPFLAG_HARBOUR) )
if( HB_SUPPORT_HARBOUR )
hb_compExprReduceASC( pSelf, HB_COMP_PARAM );
}
else if( ( ( strcmp( "STOD", pName->value.asSymbol ) == 0 ) ||
( strcmp( "HB_STOD", pName->value.asSymbol ) == 0 ) ) && usCount < 2 )
{
if( HB_COMP_ISSUPPORTED(HB_COMPFLAG_HARBOUR) )
if( HB_SUPPORT_HARBOUR )
hb_compExprReduceSTOD( pSelf, usCount, HB_COMP_PARAM );
}
}

View File

@@ -50,20 +50,13 @@
*
*/
/* TOFIX: Split the code, since MSC8 can't compile it, even in Huge model. */
/* TODO:
* - Correct post- and pre- operations to correctly handle the following code
* a[ i++ ]++
* Notice: in current implementation (an in Clipper too) 'i++' is evaluated
* two times! This causes that the new value (after incrementation) is
* stored in next element of the array.
*/
#include <math.h>
#include "hbcomp.h"
#include "hbmacro.ch"
#define HB_USE_ARRAYAT_REF
/* #define HB_USE_OBJMSG_REF */
#ifdef __WATCOMC__
/* disable warnings for 'no reference to symbol' */
#pragma warning 14 9
@@ -144,6 +137,35 @@ void hb_compExprDelOperator( HB_EXPR_PTR pExpr, HB_COMP_DECL )
*/
void hb_compExprPushOperEq( HB_EXPR_PTR pSelf, BYTE bOpEq, HB_COMP_DECL )
{
#if ! defined( HB_MACRO_SUPPORT )
BYTE bNewOp;
switch( bOpEq )
{
case HB_P_PLUS:
bNewOp = HB_P_PLUSEQ;
break;
case HB_P_MINUS:
bNewOp = HB_P_MINUSEQ;
break;
case HB_P_MULT:
bNewOp = HB_P_MULTEQ;
break;
case HB_P_DIVIDE:
bNewOp = HB_P_DIVEQ;
break;
case HB_P_MODULUS:
bNewOp = HB_P_MODEQ;
break;
case HB_P_POWER:
bNewOp = HB_P_EXPEQ;
break;
default:
bNewOp = bOpEq;
break;
}
#endif
/* NOTE: an object instance variable needs special handling
*/
if( pSelf->value.asOperator.pLeft->ExprType == HB_ET_SEND )
@@ -180,30 +202,12 @@ void hb_compExprPushOperEq( HB_EXPR_PTR pSelf, BYTE bOpEq, HB_COMP_DECL )
/* Temporary disabled optimization with references to object variables
untill we will not have extended reference items in our HVM [druzus] */
#ifdef HB_USE_OBJMSG_REF
if( bOpEq == HB_P_PLUS || bOpEq == HB_P_MINUS ||
bOpEq == HB_P_MULT || bOpEq == HB_P_DIVIDE )
if( bOpEq != bNewOp )
{
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_PUSHOVARREF );
/* push increment value */
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
/* increase operation */
switch( bOpEq )
{
case HB_P_PLUS:
bOpEq = HB_P_PLUSEQ;
break;
case HB_P_MINUS:
bOpEq = HB_P_MINUSEQ;
break;
case HB_P_MULT:
bOpEq = HB_P_MULTEQ;
break;
case HB_P_DIVIDE:
bOpEq = HB_P_DIVEQ;
break;
}
HB_EXPR_PCODE1( hb_compGenPCode1, bOpEq );
HB_EXPR_PCODE1( hb_compGenPCode1, bNewOp );
}
else
#endif
@@ -218,42 +222,58 @@ void hb_compExprPushOperEq( HB_EXPR_PTR pSelf, BYTE bOpEq, HB_COMP_DECL )
}
return;
}
/* TODO: add a special code for arrays to correctly handle a[ i++ ]++
*/
#if ! defined( HB_MACRO_SUPPORT )
else if( ( bOpEq == HB_P_PLUS || bOpEq == HB_P_MINUS ||
bOpEq == HB_P_MULT || bOpEq == HB_P_DIVIDE ) &&
( pSelf->value.asOperator.pLeft->ExprType == HB_ET_VARIABLE ) )
else if( bOpEq != bNewOp )
{
int iScope = hb_compVariableScope( HB_COMP_PARAM, pSelf->value.asOperator.pLeft->value.asSymbol );
if( iScope != HB_VS_LOCAL_FIELD && iScope != HB_VS_GLOBAL_FIELD &&
iScope != HB_VS_UNDECLARED )
#ifdef HB_USE_ARRAYAT_REF
/* NOTE: code for arrays is differ to correctly handle a[ i++ ]++ */
if( pSelf->value.asOperator.pLeft->ExprType == HB_ET_ARRAYAT )
{
HB_EXPRTYPE iType = pSelf->value.asOperator.pRight->ExprType;
if( iType == HB_ET_NUMERIC || iType == HB_ET_STRING )
if( HB_SUPPORT_HARBOUR )
{
if( iScope == HB_VS_LOCAL_VAR && iType == HB_ET_NUMERIC &&
/* Note: change type to array reference */
pSelf->value.asOperator.pLeft->value.asList.reference = TRUE;
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
pSelf->value.asOperator.pLeft->value.asList.reference = FALSE;
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
HB_EXPR_PCODE1( hb_compGenPCode1, bNewOp );
return;
}
}
else
#endif
if( pSelf->value.asOperator.pLeft->ExprType == HB_ET_VARIABLE )
{
int iScope = hb_compVariableScope( HB_COMP_PARAM, pSelf->value.asOperator.pLeft->value.asSymbol );
if( iScope != HB_VS_LOCAL_FIELD && iScope != HB_VS_GLOBAL_FIELD &&
iScope != HB_VS_UNDECLARED )
{
if( iScope == HB_VS_LOCAL_VAR &&
pSelf->value.asOperator.pRight->ExprType == HB_ET_NUMERIC &&
( bOpEq == HB_P_PLUS || bOpEq == HB_P_MINUS ) )
{
int iLocal = hb_compLocalGetPos( HB_COMP_PARAM, pSelf->value.asOperator.pLeft->value.asSymbol );
if( iLocal < 256 && hb_compExprIsInteger( pSelf->value.asOperator.pRight ) )
if( hb_compExprIsInteger( pSelf->value.asOperator.pRight ) )
{
short iIncrement = ( short ) pSelf->value.asOperator.pRight->value.asNum.val.l;
if( bOpEq != HB_P_MINUS || iIncrement >= -INT16_MAX )
{
if( bOpEq == HB_P_MINUS )
{
iIncrement = -iIncrement;
}
int iLocal = hb_compLocalGetPos( HB_COMP_PARAM, pSelf->value.asOperator.pLeft->value.asSymbol );
BYTE buffer[ 5 ];
hb_compGenPCode4( HB_P_LOCALNEARADDINT, ( BYTE ) iLocal, HB_LOBYTE( iIncrement ), HB_HIBYTE( iIncrement ), HB_COMP_PARAM );
if( bOpEq == HB_P_MINUS )
iIncrement = -iIncrement;
buffer[ 0 ] = HB_P_LOCALADDINT;
buffer[ 1 ] = HB_LOBYTE( iLocal );
buffer[ 2 ] = HB_HIBYTE( iLocal );
buffer[ 3 ] = HB_LOBYTE( iIncrement );
buffer[ 4 ] = HB_HIBYTE( iIncrement );
hb_compGenPCodeN( buffer, 5, HB_COMP_PARAM );
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
return;
}
}
@@ -263,56 +283,9 @@ void hb_compExprPushOperEq( HB_EXPR_PTR pSelf, BYTE bOpEq, HB_COMP_DECL )
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
switch( bOpEq )
{
case HB_P_PLUS:
bOpEq = HB_P_PLUSEQ;
break;
case HB_P_MINUS:
bOpEq = HB_P_MINUSEQ;
break;
case HB_P_MULT:
bOpEq = HB_P_MULTEQ;
break;
case HB_P_DIVIDE:
bOpEq = HB_P_DIVEQ;
break;
}
HB_EXPR_PCODE1( hb_compGenPCode1, bOpEq );
HB_EXPR_PCODE1( hb_compGenPCode1, bNewOp );
return;
}
else if( iType == HB_ET_VARIABLE )
{
int iScope = hb_compVariableScope( HB_COMP_PARAM, pSelf->value.asOperator.pRight->value.asSymbol );
if( iScope != HB_VS_LOCAL_FIELD && iScope != HB_VS_GLOBAL_FIELD &&
iScope != HB_VS_UNDECLARED )
{
/* NOTE: direct type change */
pSelf->value.asOperator.pLeft->ExprType = HB_ET_VARREF;
pSelf->value.asOperator.pRight->ExprType = HB_ET_VARREF;
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
switch( bOpEq )
{
case HB_P_PLUS:
bOpEq = HB_P_PLUSEQ;
break;
case HB_P_MINUS:
bOpEq = HB_P_MINUSEQ;
break;
case HB_P_MULT:
bOpEq = HB_P_MULTEQ;
break;
case HB_P_DIVIDE:
bOpEq = HB_P_DIVEQ;
break;
}
HB_EXPR_PCODE1( hb_compGenPCode1, bOpEq );
return;
}
}
}
}
#endif
@@ -332,6 +305,35 @@ void hb_compExprPushOperEq( HB_EXPR_PTR pSelf, BYTE bOpEq, HB_COMP_DECL )
*/
void hb_compExprUseOperEq( HB_EXPR_PTR pSelf, BYTE bOpEq, HB_COMP_DECL )
{
#if ! defined( HB_MACRO_SUPPORT )
BYTE bNewOp;
switch( bOpEq )
{
case HB_P_PLUS:
bNewOp = HB_P_PLUSEQPOP;
break;
case HB_P_MINUS:
bNewOp = HB_P_MINUSEQPOP;
break;
case HB_P_MULT:
bNewOp = HB_P_MULTEQPOP;
break;
case HB_P_DIVIDE:
bNewOp = HB_P_DIVEQPOP;
break;
case HB_P_MODULUS:
bNewOp = HB_P_MODEQPOP;
break;
case HB_P_POWER:
bNewOp = HB_P_EXPEQPOP;
break;
default:
bNewOp = bOpEq;
break;
}
#endif
/* NOTE: an object instance variable needs special handling
*/
if( pSelf->value.asOperator.pLeft->ExprType == HB_ET_SEND )
@@ -342,30 +344,12 @@ void hb_compExprUseOperEq( HB_EXPR_PTR pSelf, BYTE bOpEq, HB_COMP_DECL )
/* Temporary disabled optimization with references to object variables
untill we will not have extended reference items in our HVM [druzus] */
#ifdef HB_USE_OBJMSG_REF
if( bOpEq == HB_P_PLUS || bOpEq == HB_P_MINUS ||
bOpEq == HB_P_MULT || bOpEq == HB_P_DIVIDE )
if( bOpEq != bNewOp )
{
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_PUSHOVARREF );
/* push increment value */
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
/* increase operation and pop the unneeded value from the stack */
switch( bOpEq )
{
case HB_P_PLUS:
bOpEq = HB_P_PLUSEQPOP;
break;
case HB_P_MINUS:
bOpEq = HB_P_MINUSEQPOP;
break;
case HB_P_MULT:
bOpEq = HB_P_MULTEQPOP;
break;
case HB_P_DIVIDE:
bOpEq = HB_P_DIVEQPOP;
break;
}
HB_EXPR_PCODE1( hb_compGenPCode1, bOpEq );
HB_EXPR_PCODE1( hb_compGenPCode1, bNewOp );
}
else
#endif
@@ -382,39 +366,58 @@ void hb_compExprUseOperEq( HB_EXPR_PTR pSelf, BYTE bOpEq, HB_COMP_DECL )
}
return;
}
/* TODO: add a special code for arrays to correctly handle a[ i++ ]++
*/
#if ! defined( HB_MACRO_SUPPORT )
else if( ( bOpEq == HB_P_PLUS || bOpEq == HB_P_MINUS ||
bOpEq == HB_P_MULT || bOpEq == HB_P_DIVIDE ) &&
( pSelf->value.asOperator.pLeft->ExprType == HB_ET_VARIABLE ) )
else if( bOpEq != bNewOp )
{
int iScope = hb_compVariableScope( HB_COMP_PARAM, pSelf->value.asOperator.pLeft->value.asSymbol );
if( iScope != HB_VS_LOCAL_FIELD && iScope != HB_VS_GLOBAL_FIELD &&
iScope != HB_VS_UNDECLARED )
#ifdef HB_USE_ARRAYAT_REF
/* NOTE: code for arrays is differ to correctly handle a[ i++ ]++ */
if( pSelf->value.asOperator.pLeft->ExprType == HB_ET_ARRAYAT )
{
HB_EXPRTYPE iType = pSelf->value.asOperator.pRight->ExprType, iOldType;
if( iType == HB_ET_NUMERIC || iType == HB_ET_STRING )
if( HB_SUPPORT_HARBOUR )
{
if( iScope == HB_VS_LOCAL_VAR && iType == HB_ET_NUMERIC &&
/* Note: change type to array reference */
pSelf->value.asOperator.pLeft->value.asList.reference = TRUE;
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
pSelf->value.asOperator.pLeft->value.asList.reference = FALSE;
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
HB_EXPR_PCODE1( hb_compGenPCode1, bNewOp );
return;
}
}
else
#endif
if( pSelf->value.asOperator.pLeft->ExprType == HB_ET_VARIABLE )
{
int iScope = hb_compVariableScope( HB_COMP_PARAM, pSelf->value.asOperator.pLeft->value.asSymbol );
if( iScope != HB_VS_LOCAL_FIELD && iScope != HB_VS_GLOBAL_FIELD &&
iScope != HB_VS_UNDECLARED )
{
HB_EXPRTYPE iOldType;
if( iScope == HB_VS_LOCAL_VAR &&
pSelf->value.asOperator.pRight->ExprType == HB_ET_NUMERIC &&
( bOpEq == HB_P_PLUS || bOpEq == HB_P_MINUS ) )
{
int iLocal = hb_compLocalGetPos( HB_COMP_PARAM, pSelf->value.asOperator.pLeft->value.asSymbol );
if( iLocal < 256 && hb_compExprIsInteger( pSelf->value.asOperator.pRight ) )
if( hb_compExprIsInteger( pSelf->value.asOperator.pRight ) )
{
short iIncrement = ( short ) pSelf->value.asOperator.pRight->value.asNum.val.l;
if( bOpEq != HB_P_MINUS || iIncrement >= -INT16_MAX )
{
if( bOpEq == HB_P_MINUS )
{
iIncrement = -iIncrement;
}
int iLocal = hb_compLocalGetPos( HB_COMP_PARAM, pSelf->value.asOperator.pLeft->value.asSymbol );
BYTE buffer[ 5 ];
hb_compGenPCode4( HB_P_LOCALNEARADDINT, ( BYTE ) iLocal, HB_LOBYTE( iIncrement ), HB_HIBYTE( iIncrement ), HB_COMP_PARAM );
if( bOpEq == HB_P_MINUS )
iIncrement = -iIncrement;
buffer[ 0 ] = HB_P_LOCALADDINT;
buffer[ 1 ] = HB_LOBYTE( iLocal );
buffer[ 2 ] = HB_HIBYTE( iLocal );
buffer[ 3 ] = HB_LOBYTE( iIncrement );
buffer[ 4 ] = HB_HIBYTE( iIncrement );
hb_compGenPCodeN( buffer, 5, HB_COMP_PARAM );
return;
}
}
@@ -425,59 +428,10 @@ void hb_compExprUseOperEq( HB_EXPR_PTR pSelf, BYTE bOpEq, HB_COMP_DECL )
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
switch( bOpEq )
{
case HB_P_PLUS:
bOpEq = HB_P_PLUSEQPOP;
break;
case HB_P_MINUS:
bOpEq = HB_P_MINUSEQPOP;
break;
case HB_P_MULT:
bOpEq = HB_P_MULTEQPOP;
break;
case HB_P_DIVIDE:
bOpEq = HB_P_DIVEQPOP;
break;
}
HB_EXPR_PCODE1( hb_compGenPCode1, bOpEq );
HB_EXPR_PCODE1( hb_compGenPCode1, bNewOp );
pSelf->value.asOperator.pLeft->ExprType = iOldType;
return;
}
else if( iType == HB_ET_VARIABLE )
{
int iScope = hb_compVariableScope( HB_COMP_PARAM, pSelf->value.asOperator.pRight->value.asSymbol );
if( iScope != HB_VS_LOCAL_FIELD && iScope != HB_VS_GLOBAL_FIELD &&
iScope != HB_VS_UNDECLARED )
{
/* NOTE: direct type change */
iOldType = pSelf->value.asOperator.pLeft->ExprType;
pSelf->value.asOperator.pLeft->ExprType = HB_ET_VARREF;
pSelf->value.asOperator.pRight->ExprType = HB_ET_VARREF;
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
switch( bOpEq )
{
case HB_P_PLUS:
bOpEq = HB_P_PLUSEQPOP;
break;
case HB_P_MINUS:
bOpEq = HB_P_MINUSEQPOP;
break;
case HB_P_MULT:
bOpEq = HB_P_MULTEQPOP;
break;
case HB_P_DIVIDE:
bOpEq = HB_P_DIVEQPOP;
break;
}
HB_EXPR_PCODE1( hb_compGenPCode1, bOpEq );
pSelf->value.asOperator.pLeft->ExprType = iOldType;
pSelf->value.asOperator.pRight->ExprType = iType;
return;
}
}
}
}
#endif
@@ -507,15 +461,13 @@ void hb_compExprPushPreOp( HB_EXPR_PTR pSelf, BYTE bOper, HB_COMP_DECL )
#ifdef HB_USE_OBJMSG_REF
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_PUSHOVARREF );
/* increase/decrease operation */
/* increase/decrease operation, leave unreferenced value on stack */
/* We have to unreference the item on the stack, because we do not have
such PCODE(s) then I'll trnaslate HB_P_INC/HB_P_DEC into
HB_P_[PLUS|MINUS]EQ, Maybe in the future we will make it
in differ way [druzus] */
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_ONE );
bOper = ( bOper == HB_P_INC ) ? HB_P_PLUSEQ : HB_P_MINUSEQ;
HB_EXPR_PCODE1( hb_compGenPCode1, bOper );
#else
HB_EXPR_PCODE2( hb_compGenPCode2, HB_P_SENDSHORT, 0 );
@@ -525,6 +477,23 @@ void hb_compExprPushPreOp( HB_EXPR_PTR pSelf, BYTE bOper, HB_COMP_DECL )
HB_EXPR_PCODE2( hb_compGenPCode2, HB_P_SENDSHORT, 1 );
#endif
}
#ifdef HB_USE_ARRAYAT_REF
/* NOTE: code for arrays is differ to correctly handle a[ i++ ]++ */
else if( HB_SUPPORT_HARBOUR &&
pSelf->value.asOperator.pLeft->ExprType == HB_ET_ARRAYAT )
{
/* push reference to current value */
/* Note: change type to array reference */
pSelf->value.asOperator.pLeft->value.asList.reference = TRUE;
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
pSelf->value.asOperator.pLeft->value.asList.reference = FALSE;
/* increase/decrease operation, leave unreferenced value on stack */
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_ONE );
bOper = ( bOper == HB_P_INC ) ? HB_P_PLUSEQ : HB_P_MINUSEQ;
HB_EXPR_PCODE1( hb_compGenPCode1, bOper );
}
#endif
else
{
/* Push current value */
@@ -546,13 +515,47 @@ void hb_compExprPushPostOp( HB_EXPR_PTR pSelf, BYTE bOper, HB_COMP_DECL )
*/
if( pSelf->value.asOperator.pLeft->ExprType == HB_ET_SEND )
{
#ifdef HB_USE_OBJMSG_REF
/* push reference to current value */
HB_EXPR_PCODE1( hb_compExprSendPopPush, pSelf->value.asOperator.pLeft );
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_PUSHOVARREF );
/* Duplicate the reference and unref the original one -
* it will be the result of whole expression
*/
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_DUPLUNREF );
/* increment/decrement the value */
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_ONE );
bOper = ( bOper == HB_P_INC ) ? HB_P_PLUSEQPOP : HB_P_MINUSEQPOP;
HB_EXPR_PCODE1( hb_compGenPCode1, bOper );
#else
/* push current value - it will be a result of whole expression */
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
/* now increment the value */
HB_EXPR_PCODE2( hb_compExprPushPreOp, pSelf, bOper );
/* pop the value from the stack */
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_POP );
#endif
}
#ifdef HB_USE_ARRAYAT_REF
/* NOTE: code for arrays is differ to correctly handle a[ i++ ]++ */
else if( pSelf->value.asOperator.pLeft->ExprType == HB_ET_ARRAYAT )
{
/* push reference to current value */
/* Note: change type to array reference */
pSelf->value.asOperator.pLeft->value.asList.reference = TRUE;
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
pSelf->value.asOperator.pLeft->value.asList.reference = FALSE;
/* Duplicate the reference and unref the original one -
* it will be the result of whole expression
*/
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_DUPLUNREF );
/* increase/decrease operation */
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_ONE );
bOper = ( bOper == HB_P_INC ) ? HB_P_PLUSEQPOP : HB_P_MINUSEQPOP;
HB_EXPR_PCODE1( hb_compGenPCode1, bOper );
}
#endif
else
{
/* Push current value */
@@ -575,10 +578,37 @@ void hb_compExprUsePreOp( HB_EXPR_PTR pSelf, BYTE bOper, HB_COMP_DECL )
*/
if( pSelf->value.asOperator.pLeft->ExprType == HB_ET_SEND )
{
/* Temporary disabled optimization with references to object variables
untill we will not have extended reference items in our HVM [druzus] */
#ifdef HB_USE_OBJMSG_REF
/* push reference to current value */
HB_EXPR_PCODE1( hb_compExprSendPopPush, pSelf->value.asOperator.pLeft );
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_PUSHOVARREF );
/* increment/decrement the value */
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_ONE );
bOper = ( bOper == HB_P_INC ) ? HB_P_PLUSEQPOP : HB_P_MINUSEQPOP;
HB_EXPR_PCODE1( hb_compGenPCode1, bOper );
#else
HB_EXPR_PCODE2( hb_compExprPushPreOp, pSelf, bOper );
/* pop the value from the stack */
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_POP );
#endif
}
#ifdef HB_USE_ARRAYAT_REF
/* NOTE: code for arrays is differ to correctly handle a[ i++ ]++ */
else if( pSelf->value.asOperator.pLeft->ExprType == HB_ET_ARRAYAT )
{
/* push reference to current value */
/* Note: change type to array reference */
pSelf->value.asOperator.pLeft->value.asList.reference = TRUE;
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
pSelf->value.asOperator.pLeft->value.asList.reference = FALSE;
/* increase/decrease operation */
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_ONE );
bOper = ( bOper == HB_P_INC ) ? HB_P_PLUSEQPOP : HB_P_MINUSEQPOP;
HB_EXPR_PCODE1( hb_compGenPCode1, bOper );
}
#endif
else
{
/* Push current value */
@@ -611,7 +641,7 @@ void hb_compExprUseAliasMacro( HB_EXPR_PTR pAliasedVar, BYTE bAction, HB_COMP_DE
* ALIAS->&var is the same as &( "ALIAS->" + var )
*
*/
HB_EXPR_PCODE2( hb_compGenPushString, pAlias->value.asSymbol, strlen(pAlias->value.asSymbol) + 1 );
HB_EXPR_PCODE2( hb_compGenPushString, pAlias->value.asSymbol, strlen( pAlias->value.asSymbol ) + 1 );
HB_EXPR_USE( pVar, HB_EA_PUSH_PCODE );
if( bAction == HB_EA_PUSH_PCODE )
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_MACROPUSHALIASED );
@@ -624,7 +654,7 @@ void hb_compExprUseAliasMacro( HB_EXPR_PTR pAliasedVar, BYTE bAction, HB_COMP_DE
* &macro->var is the same as: &( macro + "->var" )
*/
HB_EXPR_USE( pAlias, HB_EA_PUSH_PCODE );
HB_EXPR_PCODE2( hb_compGenPushString, pVar->value.asSymbol, strlen(pVar->value.asSymbol) + 1 );
HB_EXPR_PCODE2( hb_compGenPushString, pVar->value.asSymbol, strlen( pVar->value.asSymbol ) + 1 );
if( bAction == HB_EA_PUSH_PCODE )
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_MACROPUSHALIASED );
else
@@ -727,7 +757,7 @@ BOOL hb_compExprIsValidMacro( char * szText, ULONG ulLen, BOOL *pfUseTextSubst,
*pfUseTextSubst = TRUE;
fValid = hb_compIsValidMacroVar( szSymName, HB_COMP_PARAM );
}
else if( ! HB_COMP_ISSUPPORTED(HB_COMPFLAG_HARBOUR) )
else if( ! HB_SUPPORT_HARBOUR )
*pfUseTextSubst = TRUE; /* always macro substitution in Clipper */
#endif
}

View File

@@ -221,7 +221,20 @@ typedef enum
HB_P_PUSHOVARREF, /* 147 pushes reference to object variable */
HB_P_ARRAYPUSHREF, /* 148 pushes reference to array element */
HB_P_VFRAME, /* 149 frame with variable number of parameters */
HB_P_LAST_PCODE /* 150 this defines the number of defined pcodes */
HB_P_LARGEFRAME, /* 150 frame with more then 255 locals */
HB_P_LARGEVFRAME, /* 151 frame with variable number of parameters and more then 255 locals */
HB_P_PUSHSTRHIDDEN, /* 152 places a "hidden" string on the virtual machine stack */
HB_P_LOCALADDINT, /* 153 Add/Subtract specified int into specified local without using the stack. */
HB_P_MODEQPOP, /* 154 calculates the modulus of var reference and a value */
HB_P_EXPEQPOP, /* 155 calculates the power of var reference and a value */
HB_P_MODEQ, /* 156 calculates the modulus of var reference and a value, leave result on the stack */
HB_P_EXPEQ, /* 157 calculates the power of var reference and a value, leave result on the stack */
HB_P_DUPLUNREF, /* 158 places a copy of the latest virtual machine stack value on to the stack and unreference the source one */
HB_P_MPUSHBLOCKLARGE, /* 159 code block generated by the macro compiler larger then 64kb */
HB_P_MPUSHSTRLARGE, /* 160 Macro compiled pushed string */
HB_P_PUSHBLOCKLARGE, /* 161 start of a codeblock definition */
HB_P_PUSHSTRLARGE, /* 162 places a string on the virtual machine stack */
HB_P_LAST_PCODE /* 163 this defines the number of defined pcodes */
} HB_PCODE;
#endif /* HB_PCODE_H_ */

View File

@@ -91,6 +91,7 @@ extern HB_EXPORT void hb_xvmWithObjectMessage( PHB_SYMB ); /* send WITH O
extern HB_EXPORT void hb_xvmSetLine( USHORT uiLine ); /* set .prg line number information */
extern HB_EXPORT void hb_xvmFrame( int iLocals, int iParams ); /* increases the stack pointer for the amount of locals and params suplied */
extern HB_EXPORT void hb_xvmVFrame( int iLocals, int iParams ); /* increases the stack pointer for the amount of locals and variable params */
extern HB_EXPORT void hb_xvmSFrame( PHB_SYMB pSymbol );
extern HB_EXPORT void hb_xvmStatics( PHB_SYMB pSymbol, USHORT uiStatics );
extern HB_EXPORT void hb_xvmParameter( PHB_SYMB pSymbol, int iParams );
@@ -106,6 +107,7 @@ extern HB_EXPORT BOOL hb_xvmPushVariable( PHB_SYMB pSymbol );
extern HB_EXPORT BOOL hb_xvmPopVariable( PHB_SYMB pSymbol );
extern HB_EXPORT void hb_xvmPushBlock( const BYTE * pCode, PHB_SYMB pSymbols ); /* creates a codeblock */
extern HB_EXPORT void hb_xvmPushBlockShort( const BYTE * pCode, PHB_SYMB pSymbols ); /* creates a codeblock */
extern HB_EXPORT void hb_xvmPushBlockLarge( const BYTE * pCode, PHB_SYMB pSymbols ); /* creates a codeblock */
extern HB_EXPORT void hb_xvmPushSelf( void );
extern HB_EXPORT void hb_xvmPushLocal( SHORT iLocal ); /* pushes the containts of a local onto the stack */
extern HB_EXPORT void hb_xvmPushLocalByRef( SHORT iLocal ); /* pushes a local by refrence onto the stack */
@@ -129,8 +131,8 @@ extern HB_EXPORT BOOL hb_xvmAnd( void );
extern HB_EXPORT BOOL hb_xvmOr( void );
extern HB_EXPORT BOOL hb_xvmNot( void );
extern HB_EXPORT BOOL hb_xvmNegate( void );
extern HB_EXPORT BOOL hb_xvmPower( void );
extern HB_EXPORT void hb_xvmDuplicate( void );
extern HB_EXPORT void hb_xvmDuplUnRef( void );
extern HB_EXPORT void hb_xvmDuplTwo( void );
extern HB_EXPORT BOOL hb_xvmForTest( void );
extern HB_EXPORT void hb_xvmFuncPtr( void );
@@ -154,6 +156,11 @@ extern HB_EXPORT BOOL hb_xvmDivide( void ); /* divides the
extern HB_EXPORT BOOL hb_xvmDivEq( void );
extern HB_EXPORT BOOL hb_xvmDivEqPop( void );
extern HB_EXPORT BOOL hb_xvmModulus( void ); /* calculates the modulus of latest two values on the stack, removes them and leaves the result */
extern HB_EXPORT BOOL hb_xvmModEq( void );
extern HB_EXPORT BOOL hb_xvmModEqPop( void );
extern HB_EXPORT BOOL hb_xvmPower( void );
extern HB_EXPORT BOOL hb_xvmExpEq( void );
extern HB_EXPORT BOOL hb_xvmExpEqPop( void );
extern HB_EXPORT BOOL hb_xvmInc( void );
extern HB_EXPORT BOOL hb_xvmDec( void );
@@ -183,6 +190,7 @@ extern HB_EXPORT BOOL hb_xvmMacroPopAliased( BYTE bFlags );
extern HB_EXPORT BOOL hb_xvmMacroSymbol( void );
extern HB_EXPORT BOOL hb_xvmMacroText( void );
extern HB_EXPORT void hb_xvmPushStringHidden( char * szText, ULONG length );
extern HB_EXPORT void hb_xvmPushDouble( double dNumber, int iWidth, int iDec );
#ifdef HB_LONG_LONG_OFF
extern HB_EXPORT void hb_xvmPushLongLong( double dNumber );

View File

@@ -50,14 +50,6 @@
*
*/
/* TODO:
* - Correct post- and pre- operations to correctly handle the following code
* a[ i++ ]++
* Notice: in current implementation (an in Clipper too) 'i++' is evaluated
* two times! This causes that the new value (after incrementation) is
* stored in next element of the array.
*/
/* NOTE: This must be the first definition
* This is a common code shared by macro and standalone compiler
*/

View File

@@ -50,16 +50,6 @@
*
*/
/* TOFIX: Split the code, since MSC8 can't compile it, even in Huge model. */
/* TODO:
* - Correct post- and pre- operations to correctly handle the following code
* a[ i++ ]++
* Notice: in current implementation (an in Clipper too) 'i++' is evaluated
* two times! This causes that the new value (after incrementation) is
* stored in next element of the array.
*/
/* NOTE: This must be the first definition
* This is a common code shared by macro and standalone compiler
*/
@@ -364,7 +354,7 @@ HB_EXPR_PTR hb_compExprReduceMinus( HB_EXPR_PTR pSelf, HB_COMP_DECL )
else if( pLeft->ExprType == HB_ET_STRING && pRight->ExprType == HB_ET_STRING )
{
/* TODO:
*/
*/
}
else
{

View File

@@ -945,3 +945,33 @@ char * hb_strRemEscSeq( char *str, ULONG *pLen )
return str;
}
char * hb_compEncodeString( int iMethod, const char * szText, ULONG * pulLen )
{
char * pBuffer = ( char * ) hb_xgrab( *pulLen + 1 );
memcpy( pBuffer, szText, *pulLen );
pBuffer[ *pulLen ] = '\0';
if( iMethod == 1 )
{
ULONG ul;
for( ul = 0; ul < *pulLen; ul++ )
pBuffer[ ul ] ^= 0xF3;
}
return pBuffer;
}
char * hb_compDecodeString( int iMethod, const char * szText, ULONG * pulLen )
{
char * pBuffer = ( char * ) hb_xgrab( *pulLen + 1 );
memcpy( pBuffer, szText, *pulLen );
pBuffer[ *pulLen ] = '\0';
if( iMethod == 1 )
{
ULONG ul;
for( ul = 0; ul < *pulLen; ul++ )
pBuffer[ ul ] ^= 0xF3;
}
return pBuffer;
}

View File

@@ -865,22 +865,31 @@ void hb_compChkCompilerSwitch( HB_COMP_DECL, int iArg, char *Args[] )
szStrEnv = hb_getenv( "CLIPPERCMD" );
}
if( szStrEnv && szStrEnv[0] != '\0' )
{
char *szSwitch = strtok( szStrEnv, " " );
/* Check the environment var
while it isn't empty.
*/
while( szSwitch != NULL && !HB_COMP_PARAM->fExit )
{
hb_compChkEnvironVar( HB_COMP_PARAM, szSwitch );
szSwitch = strtok( NULL, " " );
}
}
if( szStrEnv )
{
char *szSwitch, *szPtr;
szPtr = szStrEnv;
while( *szPtr && !HB_COMP_PARAM->fExit )
{
while( *szPtr == ' ' )
++szPtr;
szSwitch = szPtr;
if( *szSwitch )
{
while( *++szPtr )
{
if( *szPtr == ' ' )
{
*szPtr++ = '\0';
break;
}
}
hb_compChkEnvironVar( HB_COMP_PARAM, szSwitch );
}
}
hb_xfree( ( void * ) szStrEnv );
}
}
}
@@ -943,7 +952,7 @@ static void hb_compChkDefineSwitch( HB_COMP_DECL, char *pszSwitch )
void hb_compChkDefines( HB_COMP_DECL, int iArg, char *Args[] )
{
/* Chech the environment variables */
/* Check the environment variables */
{
/* NOTE: CLIPPERCMD enviroment variable is overriden
if HARBOURCMD exists */
@@ -957,20 +966,31 @@ void hb_compChkDefines( HB_COMP_DECL, int iArg, char *Args[] )
szStrEnv = hb_getenv( "CLIPPERCMD" );
}
if( szStrEnv && szStrEnv[0] != '\0' )
{
char *szSwitch = strtok( szStrEnv, " " );
/* Check the environment var while it isn't empty. */
while( szSwitch != NULL )
{
hb_compChkDefineSwitch( HB_COMP_PARAM, szSwitch );
szSwitch = strtok( NULL, " " );
}
}
if( szStrEnv )
{
char *szSwitch, *szPtr;
szPtr = szStrEnv;
while( *szPtr && !HB_COMP_PARAM->fExit )
{
while( *szPtr == ' ' )
++szPtr;
szSwitch = szPtr;
if( *szSwitch )
{
while( *++szPtr )
{
if( *szPtr == ' ' )
{
*szPtr++ = '\0';
break;
}
}
hb_compChkDefineSwitch( HB_COMP_PARAM, szSwitch );
}
}
hb_xfree( ( void * ) szStrEnv );
}
}
/* Check the command line options */

View File

@@ -382,6 +382,27 @@ static void hb_compGenCFunc( FILE * yyc, char *cDecor, char *szName, int iStrip
}
}
static void hb_compGenCByteStr( FILE * yyc, BYTE * pText, ULONG ulLen )
{
ULONG ulPos;
for( ulPos = 0; ulPos < ulLen; ulPos++ )
{
BYTE uchr = ( BYTE ) pText[ ulPos ];
/*
* NOTE: After optimization some CHR(n) can be converted
* into a string containing nonprintable characters.
*
* TODO: add switch to use hexadecimal format "%#04x"
*/
if( ( uchr < ( BYTE ) ' ' ) || ( uchr >= 127 ) )
fprintf( yyc, "%i, ", uchr );
else if( strchr( "\'\\\"", uchr ) )
fprintf( yyc, "%i, ", uchr );
else
fprintf( yyc, "\'%c\', ", uchr );
}
}
static HB_GENC_FUNC( hb_p_and )
{
HB_SYMBOL_UNUSED( pFunc );
@@ -469,6 +490,15 @@ static HB_GENC_FUNC( hb_p_duplicate )
return 1;
}
static HB_GENC_FUNC( hb_p_duplunref )
{
HB_SYMBOL_UNUSED( pFunc );
HB_SYMBOL_UNUSED( lPCodePos );
fprintf( cargo->yyc, "\tHB_P_DUPLUNREF,\n" );
return 1;
}
static HB_GENC_FUNC( hb_p_dupltwo )
{
HB_SYMBOL_UNUSED( pFunc );
@@ -1234,6 +1264,20 @@ static HB_GENC_FUNC( hb_p_pushaliasedvar )
return 3;
}
static HB_GENC_FUNC( hb_p_pushblockshort )
{
++cargo->iNestedCodeblock;
fprintf( cargo->yyc, "\tHB_P_PUSHBLOCKSHORT, %i,",
pFunc->pCode[ lPCodePos + 1 ] );
if( cargo->bVerbose )
fprintf( cargo->yyc, "\t/* %i */",
pFunc->pCode[ lPCodePos + 1 ] );
fprintf( cargo->yyc, "\n" );
return 2;
}
static HB_GENC_FUNC( hb_p_pushblock )
{
USHORT wVar, w;
@@ -1246,17 +1290,17 @@ static HB_GENC_FUNC( hb_p_pushblock )
pFunc->pCode[ lPCodePos + 2 ] );
if( cargo->bVerbose )
fprintf( cargo->yyc, "\t/* %i */",
HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) ) );
HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] ) );
fprintf( cargo->yyc, "\n" );
w = HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 3 ] ) );
w = HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 3 ] );
fprintf( cargo->yyc, "\t%i, %i,",
pFunc->pCode[ lPCodePos + 3 ],
pFunc->pCode[ lPCodePos + 4 ] );
if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* number of local parameters (%i) */", w );
fprintf( cargo->yyc, "\n" );
wVar = HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 5 ] ) );
wVar = HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 5 ] );
fprintf( cargo->yyc, "\t%i, %i,",
pFunc->pCode[ lPCodePos + 5 ],
pFunc->pCode[ lPCodePos + 6 ] );
@@ -1267,7 +1311,7 @@ static HB_GENC_FUNC( hb_p_pushblock )
/* create the table of referenced local variables */
while( wVar-- )
{
w = HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos ] ) );
w = HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos ] );
fprintf( cargo->yyc, "\t%i, %i,",
pFunc->pCode[ lPCodePos ],
pFunc->pCode[ lPCodePos + 1 ] );
@@ -1285,18 +1329,56 @@ static HB_GENC_FUNC( hb_p_pushblock )
return (lPCodePos - ulStart);
}
static HB_GENC_FUNC( hb_p_pushblockshort )
static HB_GENC_FUNC( hb_p_pushblocklarge )
{
USHORT wVar, w;
ULONG ulStart = lPCodePos;
++cargo->iNestedCodeblock;
fprintf( cargo->yyc, "\tHB_P_PUSHBLOCKSHORT, %i,",
pFunc->pCode[ lPCodePos + 1 ] );
fprintf( cargo->yyc, "\tHB_P_PUSHBLOCKLARGE, %i, %i, %i,",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ],
pFunc->pCode[ lPCodePos + 3 ] );
if( cargo->bVerbose )
fprintf( cargo->yyc, "\t/* %i */",
pFunc->pCode[ lPCodePos + 1 ] );
fprintf( cargo->yyc, "\t/* %lu */",
HB_PCODE_MKUINT24( &pFunc->pCode[ lPCodePos + 1 ] ) );
fprintf( cargo->yyc, "\n" );
return 2;
w = HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 4 ] );
fprintf( cargo->yyc, "\t%i, %i,",
pFunc->pCode[ lPCodePos + 4 ],
pFunc->pCode[ lPCodePos + 5 ] );
if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* number of local parameters (%i) */", w );
fprintf( cargo->yyc, "\n" );
wVar = HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 6 ] );
fprintf( cargo->yyc, "\t%i, %i,",
pFunc->pCode[ lPCodePos + 6 ],
pFunc->pCode[ lPCodePos + 7 ] );
if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* number of local variables (%i) */", wVar );
fprintf( cargo->yyc, "\n" );
lPCodePos += 8; /* codeblock size + number of parameters + number of local variables */
/* create the table of referenced local variables */
while( wVar-- )
{
w = HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos ] );
fprintf( cargo->yyc, "\t%i, %i,",
pFunc->pCode[ lPCodePos ],
pFunc->pCode[ lPCodePos + 1 ] );
/* NOTE:
* When a codeblock is used to initialize a static variable
* the names of local variables cannot be determined
* because at the time of C code generation we don't know
* in which function was defined this local variable
*/
if( ( pFunc->cScope & HB_FS_INITEXIT ) != HB_FS_INITEXIT )
if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* %s */", hb_compLocalVariableFind( pFunc, w )->szName );
fprintf( cargo->yyc, "\n" );
lPCodePos +=2;
}
return (lPCodePos - ulStart);
}
static HB_GENC_FUNC( hb_p_pushdouble )
@@ -1535,14 +1617,30 @@ static HB_GENC_FUNC( hb_p_pushstaticref )
fprintf( cargo->yyc, "\t/* %s */", szName );
}
fprintf( cargo->yyc, "\n" );
return 3;
}
static HB_GENC_FUNC( hb_p_pushstrshort )
{
USHORT wLen = pFunc->pCode[ lPCodePos + 1 ];
fprintf( cargo->yyc, "\tHB_P_PUSHSTRSHORT, %i,", pFunc->pCode[ lPCodePos + 1 ] );
if( cargo->bVerbose )
fprintf( cargo->yyc, "\t/* %i */", wLen );
if( wLen > 0 )
{
fprintf( cargo->yyc, "\n\t" );
hb_compGenCByteStr( cargo->yyc, &pFunc->pCode[ lPCodePos + 2 ], wLen );
}
fprintf( cargo->yyc, "\n" );
return wLen + 2;
}
static HB_GENC_FUNC( hb_p_pushstr )
{
ULONG ulStart = lPCodePos;
USHORT wLen = HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 1 ] ) );
USHORT wLen = HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] );
fprintf( cargo->yyc, "\tHB_P_PUSHSTR, %i, %i,",
pFunc->pCode[ lPCodePos + 1 ],
@@ -1551,66 +1649,55 @@ static HB_GENC_FUNC( hb_p_pushstr )
if( cargo->bVerbose )
fprintf( cargo->yyc, "\t/* %i */", wLen );
lPCodePos += 3;
if( wLen > 0 )
{
fprintf( cargo->yyc, "\n\t" );
while( wLen-- )
{
BYTE uchr = ( BYTE ) pFunc->pCode[ lPCodePos++ ];
/*
* NOTE: After optimization some CHR(n) can be converted
* into a string containing nonprintable characters.
*
* TODO: add switch to use hexadecimal format "%#04x"
*/
if( ( uchr < ( BYTE ) ' ' ) || ( uchr >= 127 ) )
fprintf( cargo->yyc, "%i, ", uchr );
else if( strchr( "\'\\\"", uchr ) )
fprintf( cargo->yyc, "%i, ", uchr );
else
fprintf( cargo->yyc, "\'%c\', ", uchr );
}
hb_compGenCByteStr( cargo->yyc, &pFunc->pCode[ lPCodePos + 3 ], wLen );
}
fprintf( cargo->yyc, "\n" );
return ( lPCodePos - ulStart );
return wLen + 3;
}
static HB_GENC_FUNC( hb_p_pushstrshort )
static HB_GENC_FUNC( hb_p_pushstrlarge )
{
ULONG ulStart = lPCodePos;
USHORT wLen = pFunc->pCode[ lPCodePos + 1 ];
ULONG ulLen = HB_PCODE_MKUINT24( &pFunc->pCode[ lPCodePos + 1 ] );
fprintf( cargo->yyc, "\tHB_P_PUSHSTRSHORT, %i,", pFunc->pCode[ lPCodePos + 1 ] );
fprintf( cargo->yyc, "\tHB_P_PUSHSTRLARGE, %i, %i, %i,",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ],
pFunc->pCode[ lPCodePos + 3 ] );
if( cargo->bVerbose )
fprintf( cargo->yyc, "\t/* %lu */", ulLen );
if( ulLen > 0 )
{
fprintf( cargo->yyc, "\n\t" );
hb_compGenCByteStr( cargo->yyc, &pFunc->pCode[ lPCodePos + 4 ], ulLen );
}
fprintf( cargo->yyc, "\n" );
return ulLen + 4;
}
static HB_GENC_FUNC( hb_p_pushstrhidden )
{
USHORT wLen = HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 2 ] );
fprintf( cargo->yyc, "\tHB_P_PUSHSTRHIDDEN, %i, %i, %i,",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ],
pFunc->pCode[ lPCodePos + 3 ] );
if( cargo->bVerbose )
fprintf( cargo->yyc, "\t/* %i */", wLen );
lPCodePos += 2;
if( wLen > 0 )
{
fprintf( cargo->yyc, "\n\t" );
while( wLen-- )
{
BYTE uchr = ( BYTE ) pFunc->pCode[ lPCodePos++ ];
/*
* NOTE: After optimization some CHR(n) can be converted
* into a string containing nonprintable characters.
*
* TODO: add switch to use hexadecimal format "%#04x"
*/
if( ( uchr < ( BYTE ) ' ' ) || ( uchr >= 127 ) )
fprintf( cargo->yyc, "%i, ", uchr );
else if( strchr( "\'\\\"", uchr ) )
fprintf( cargo->yyc, "%i, ", uchr );
else
fprintf( cargo->yyc, "\'%c\', ", uchr );
}
hb_compGenCByteStr( cargo->yyc, &pFunc->pCode[ lPCodePos + 4 ], wLen );
}
fprintf( cargo->yyc, "\n" );
return ( lPCodePos - ulStart );
return wLen + 4;
}
static HB_GENC_FUNC( hb_p_pushsym )
@@ -1910,6 +1997,24 @@ static HB_GENC_FUNC( hb_p_localnearaddint )
return 4;
}
static HB_GENC_FUNC( hb_p_localaddint )
{
fprintf( cargo->yyc, "\tHB_P_LOCALADDINT, %i, %i, %i, %i,", pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ],
pFunc->pCode[ lPCodePos + 3 ],
pFunc->pCode[ lPCodePos + 4 ] );
if( cargo->bVerbose )
{
fprintf( cargo->yyc, "\t/* %s %i*/", hb_compLocalVariableFind( pFunc, HB_PCODE_MKSHORT( &pFunc->pCode[ lPCodePos + 1 ] ) )->szName,
HB_PCODE_MKSHORT( &( pFunc->pCode[ lPCodePos + 3 ] ) ) );
}
fprintf( cargo->yyc, "\n" );
return 5;
}
static HB_GENC_FUNC( hb_p_pluseqpop )
{
HB_SYMBOL_UNUSED( pFunc );
@@ -1946,6 +2051,24 @@ static HB_GENC_FUNC( hb_p_diveqpop )
return 1;
}
static HB_GENC_FUNC( hb_p_modeqpop )
{
HB_SYMBOL_UNUSED( pFunc );
HB_SYMBOL_UNUSED( lPCodePos );
fprintf( cargo->yyc, "\tHB_P_MODEQPOP,\n" );
return 1;
}
static HB_GENC_FUNC( hb_p_expeqpop )
{
HB_SYMBOL_UNUSED( pFunc );
HB_SYMBOL_UNUSED( lPCodePos );
fprintf( cargo->yyc, "\tHB_P_EXPEQPOP,\n" );
return 1;
}
static HB_GENC_FUNC( hb_p_pluseq )
{
HB_SYMBOL_UNUSED( pFunc );
@@ -1982,6 +2105,24 @@ static HB_GENC_FUNC( hb_p_diveq )
return 1;
}
static HB_GENC_FUNC( hb_p_modeq )
{
HB_SYMBOL_UNUSED( pFunc );
HB_SYMBOL_UNUSED( lPCodePos );
fprintf( cargo->yyc, "\tHB_P_MODEQ,\n" );
return 1;
}
static HB_GENC_FUNC( hb_p_expeq )
{
HB_SYMBOL_UNUSED( pFunc );
HB_SYMBOL_UNUSED( lPCodePos );
fprintf( cargo->yyc, "\tHB_P_EXPEQ,\n" );
return 1;
}
static HB_GENC_FUNC( hb_p_withobjectstart )
{
HB_SYMBOL_UNUSED( pFunc );
@@ -2020,6 +2161,28 @@ static HB_GENC_FUNC( hb_p_vframe )
return 3;
}
static HB_GENC_FUNC( hb_p_largeframe )
{
fprintf( cargo->yyc, "\tHB_P_LARGEFRAME, %i, %i, %i,",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ],
pFunc->pCode[ lPCodePos + 3 ] );
if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* locals, params */" );
fprintf( cargo->yyc, "\n" );
return 4;
}
static HB_GENC_FUNC( hb_p_largevframe )
{
fprintf( cargo->yyc, "\tHB_P_LARGEVFRAME, %i, %i, %i,",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ],
pFunc->pCode[ lPCodePos + 3 ] );
if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* locals, params */" );
fprintf( cargo->yyc, "\n" );
return 4;
}
/* NOTE: The order of functions have to match the order of opcodes
* mnemonics
*/
@@ -2178,7 +2341,20 @@ static HB_GENC_FUNC_PTR s_verbose_table[] = {
hb_p_macrosend,
hb_p_pushovarref,
hb_p_arraypushref,
hb_p_vframe
hb_p_vframe,
hb_p_largeframe,
hb_p_largevframe,
hb_p_pushstrhidden,
hb_p_localaddint,
hb_p_modeqpop,
hb_p_expeqpop,
hb_p_modeq,
hb_p_expeq,
hb_p_duplunref,
hb_p_dummy,
hb_p_dummy,
hb_p_pushblocklarge,
hb_p_pushstrlarge
};
static void hb_compGenCReadable( HB_COMP_DECL, PFUNCTION pFunc, FILE * yyc )

View File

@@ -47,14 +47,14 @@ typedef HB_GENC_FUNC_ * HB_GENC_FUNC_PTR;
fprintf( cargo->yyc, "\t#error: \"" s "\"\n" ); \
} while( 0 )
void hb_compGenCString( FILE * yyc, BYTE * pText, USHORT usLen )
void hb_compGenCString( FILE * yyc, BYTE * pText, ULONG ulLen )
{
USHORT usPos;
ULONG ulPos;
fputc( '"', yyc );
for( usPos = 0; usPos < usLen; usPos++ )
for( ulPos = 0; ulPos < ulLen; ulPos++ )
{
BYTE uchr = ( BYTE ) pText[ usPos ];
BYTE uchr = ( BYTE ) pText[ ulPos ];
/*
* NOTE: After optimization some CHR(n) can be converted
* into a string containing nonprintable characters.
@@ -294,6 +294,14 @@ static HB_GENC_FUNC( hb_p_duplicate )
return 1;
}
static HB_GENC_FUNC( hb_p_duplunref )
{
HB_GENC_LABEL();
fprintf( cargo->yyc, "\thb_xvmDuplUnRef();\n" );
return 1;
}
static HB_GENC_FUNC( hb_p_dupltwo )
{
HB_GENC_LABEL();
@@ -933,30 +941,6 @@ static HB_GENC_FUNC( hb_p_pushaliasedvar )
return 3;
}
static HB_GENC_FUNC( hb_p_pushblock )
{
USHORT usSize, us;
HB_GENC_LABEL();
usSize = HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] ) - 3;
fprintf( cargo->yyc, "\t{\n\t\tstatic const BYTE codeblock[ %hd ] = {", usSize );
for( us = 0; us < usSize; ++us )
{
if( ( us & 0x0f ) == 0 )
fprintf( cargo->yyc, "\n\t\t\t" );
if( us == usSize - 1 )
fprintf( cargo->yyc, "%d", pFunc->pCode[ lPCodePos + 3 + us ] );
else
fprintf( cargo->yyc, "%d, ", pFunc->pCode[ lPCodePos + 3 + us ] );
}
fprintf( cargo->yyc, " };\n\t\thb_xvmPushBlock( codeblock, symbols );\n\t}\n" );
return 3 + usSize;
}
static HB_GENC_FUNC( hb_p_pushblockshort )
{
USHORT usSize, us;
@@ -964,6 +948,7 @@ static HB_GENC_FUNC( hb_p_pushblockshort )
HB_GENC_LABEL();
usSize = pFunc->pCode[ lPCodePos + 1 ] - 2;
lPCodePos += 2;
fprintf( cargo->yyc, "\t{\n\t\tstatic const BYTE codeblock[ %hd ] = {", usSize );
@@ -972,15 +957,65 @@ static HB_GENC_FUNC( hb_p_pushblockshort )
if( ( us & 0x0f ) == 0 )
fprintf( cargo->yyc, "\n\t\t\t" );
if( us == usSize - 1 )
fprintf( cargo->yyc, "%d", pFunc->pCode[ lPCodePos + 2 + us ] );
fprintf( cargo->yyc, "%d", pFunc->pCode[ lPCodePos + us ] );
else
fprintf( cargo->yyc, "%d, ", pFunc->pCode[ lPCodePos + 2 + us ] );
fprintf( cargo->yyc, "%d, ", pFunc->pCode[ lPCodePos + us ] );
}
fprintf( cargo->yyc, " };\n\t\thb_xvmPushBlockShort( codeblock, symbols );\n\t}\n" );
return 2 + usSize;
}
static HB_GENC_FUNC( hb_p_pushblock )
{
USHORT usSize, us;
HB_GENC_LABEL();
usSize = HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] ) - 3;
lPCodePos += 3;
fprintf( cargo->yyc, "\t{\n\t\tstatic const BYTE codeblock[ %hd ] = {", usSize );
for( us = 0; us < usSize; ++us )
{
if( ( us & 0x0f ) == 0 )
fprintf( cargo->yyc, "\n\t\t\t" );
if( us == usSize - 1 )
fprintf( cargo->yyc, "%d", pFunc->pCode[ lPCodePos + us ] );
else
fprintf( cargo->yyc, "%d, ", pFunc->pCode[ lPCodePos + us ] );
}
fprintf( cargo->yyc, " };\n\t\thb_xvmPushBlock( codeblock, symbols );\n\t}\n" );
return 3 + usSize;
}
static HB_GENC_FUNC( hb_p_pushblocklarge )
{
ULONG ulSize, ul;
HB_GENC_LABEL();
ulSize = HB_PCODE_MKUINT24( &pFunc->pCode[ lPCodePos + 1 ] ) - 4;
lPCodePos += 4;
fprintf( cargo->yyc, "\t{\n\t\tstatic const BYTE codeblock[ %lu ] = {", ulSize );
for( ul = 0; ul < ulSize; ++ul )
{
if( ( ul & 0x0f ) == 0 )
fprintf( cargo->yyc, "\n\t\t\t" );
if( ul == ulSize - 1 )
fprintf( cargo->yyc, "%d", pFunc->pCode[ lPCodePos + ul ] );
else
fprintf( cargo->yyc, "%d, ", pFunc->pCode[ lPCodePos + ul ] );
}
fprintf( cargo->yyc, " };\n\t\thb_xvmPushBlock( codeblock, symbols );\n\t}\n" );
return 4 + ulSize;
}
static HB_GENC_FUNC( hb_p_pushdouble )
{
HB_GENC_LABEL();
@@ -1162,6 +1197,19 @@ static HB_GENC_FUNC( hb_p_pushstaticref )
return 3;
}
static HB_GENC_FUNC( hb_p_pushstrshort )
{
USHORT usLen = pFunc->pCode[ lPCodePos + 1 ] - 1;
HB_GENC_LABEL();
fprintf( cargo->yyc, "\thb_xvmPushStringConst( " );
hb_compGenCString( cargo->yyc, &pFunc->pCode[ lPCodePos + 2 ], usLen );
fprintf( cargo->yyc, ", %hu );\n", usLen );
return 3 + usLen;
}
static HB_GENC_FUNC( hb_p_pushstr )
{
USHORT usLen = HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] ) - 1;
@@ -1175,17 +1223,30 @@ static HB_GENC_FUNC( hb_p_pushstr )
return 4 + usLen;
}
static HB_GENC_FUNC( hb_p_pushstrshort )
static HB_GENC_FUNC( hb_p_pushstrlarge )
{
USHORT usLen = pFunc->pCode[ lPCodePos + 1 ] - 1;
ULONG ulLen = HB_PCODE_MKUINT24( &pFunc->pCode[ lPCodePos + 1 ] ) - 1;
HB_GENC_LABEL();
fprintf( cargo->yyc, "\thb_xvmPushStringConst( " );
hb_compGenCString( cargo->yyc, &pFunc->pCode[ lPCodePos + 2 ], usLen );
hb_compGenCString( cargo->yyc, &pFunc->pCode[ lPCodePos + 4 ], ulLen );
fprintf( cargo->yyc, ", %lu );\n", ulLen );
return 5 + ulLen;
}
static HB_GENC_FUNC( hb_p_pushstrhidden )
{
USHORT usLen = HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 2 ] );
HB_GENC_LABEL();
fprintf( cargo->yyc, "\thb_xvmPushStringHidden( " );
hb_compGenCString( cargo->yyc, &pFunc->pCode[ lPCodePos + 4 ], usLen );
fprintf( cargo->yyc, ", %hu );\n", usLen );
return 3 + usLen;
return 4 + usLen;
}
static HB_GENC_FUNC( hb_p_pushsym )
@@ -1496,6 +1557,16 @@ static HB_GENC_FUNC( hb_p_localnearaddint )
return 4;
}
static HB_GENC_FUNC( hb_p_localaddint )
{
HB_GENC_LABEL();
fprintf( cargo->yyc, "\tif( hb_xvmLocalAddInt( %d, %d ) ) break;\n",
HB_PCODE_MKSHORT( &pFunc->pCode[ lPCodePos + 1 ] ),
HB_PCODE_MKSHORT( &pFunc->pCode[ lPCodePos + 3 ] ) );
return 5;
}
static HB_GENC_FUNC( hb_p_pluseqpop )
{
HB_GENC_LABEL();
@@ -1528,6 +1599,22 @@ static HB_GENC_FUNC( hb_p_diveqpop )
return 1;
}
static HB_GENC_FUNC( hb_p_modeqpop )
{
HB_GENC_LABEL();
fprintf( cargo->yyc, "\tif( hb_xvmModEqPop() ) break;\n" );
return 1;
}
static HB_GENC_FUNC( hb_p_expeqpop )
{
HB_GENC_LABEL();
fprintf( cargo->yyc, "\tif( hb_xvmExpEqPop() ) break;\n" );
return 1;
}
static HB_GENC_FUNC( hb_p_pluseq )
{
HB_GENC_LABEL();
@@ -1560,6 +1647,22 @@ static HB_GENC_FUNC( hb_p_diveq )
return 1;
}
static HB_GENC_FUNC( hb_p_modeq )
{
HB_GENC_LABEL();
fprintf( cargo->yyc, "\tif( hb_xvmModEq() ) break;\n" );
return 1;
}
static HB_GENC_FUNC( hb_p_expeq )
{
HB_GENC_LABEL();
fprintf( cargo->yyc, "\tif( hb_xvmExpEq() ) break;\n" );
return 1;
}
static HB_GENC_FUNC( hb_p_withobjectstart )
{
HB_GENC_LABEL();
@@ -1595,6 +1698,26 @@ static HB_GENC_FUNC( hb_p_vframe )
return 3;
}
static HB_GENC_FUNC( hb_p_largeframe )
{
HB_GENC_LABEL();
fprintf( cargo->yyc, "\thb_xvmFrame( %hu, %hu );\n",
HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] ),
pFunc->pCode[ lPCodePos + 3 ] );
return 4;
}
static HB_GENC_FUNC( hb_p_largevframe )
{
HB_GENC_LABEL();
fprintf( cargo->yyc, "\thb_xvmVFrame( %hu, %hu );\n",
HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] ),
pFunc->pCode[ lPCodePos + 3 ] );
return 4;
}
/* NOTE: The order of functions have to match the order of opcodes
* mnemonics
@@ -1754,7 +1877,20 @@ static HB_GENC_FUNC_PTR s_verbose_table[] = {
hb_p_macrosend,
hb_p_pushovarref,
hb_p_arraypushref,
hb_p_vframe
hb_p_vframe,
hb_p_largeframe,
hb_p_largevframe,
hb_p_pushstrhidden,
hb_p_localaddint,
hb_p_modeqpop,
hb_p_expeqpop,
hb_p_modeq,
hb_p_expeq,
hb_p_duplunref,
hb_p_dummy,
hb_p_dummy,
hb_p_pushblocklarge,
hb_p_pushstrlarge
};
void hb_compGenCRealCode( HB_COMP_DECL, PFUNCTION pFunc, FILE * yyc )

View File

@@ -29,16 +29,68 @@
#include "hbcomp.h"
#include "hb_io.h"
/* Prototype */
static char * hb_searchpath( const char *, char *, char * );
#define HB_CFG_FILENAME "harbour.cfg"
/* QUESTION: Allocate buffer dynamically ? */
#define HB_CFG_LINE_LEN ( _POSIX_PATH_MAX )
#if defined( HOST_OS_UNIX_COMPATIBLE )
#define HB_NULL_STR " > /dev/null"
#define HB_ACCESS_FLAG F_OK
#elif defined( OS_DOS_COMPATIBLE )
#define HB_NULL_STR " >nul"
#define HB_ACCESS_FLAG 0
#else
#define HB_ACCESS_FLAG 0
#endif
/*--------------------------------------------------------------------------*/
static char * hb_searchpath( const char * pszFile, char * pszEnv, char * pszCfg )
{
char * pszPath;
BOOL bFound = FALSE;
/* Check current dir first */
if( access( ( const char * ) pszFile, HB_ACCESS_FLAG ) == 0 )
{
snprintf( pszCfg, _POSIX_PATH_MAX + 1, "%s", pszFile );
return ( char * ) pszFile;
}
else
{
/* Check if pszFile exists somewhere in the path */
while( * pszEnv )
{
pszPath = pszEnv;
while( *pszEnv )
{
if( *pszEnv == OS_PATH_LIST_SEPARATOR )
{
*pszEnv++ = '\0';
break;
}
pszEnv++;
}
if( *pszPath )
{
snprintf( pszCfg, _POSIX_PATH_MAX + 1, "%s%c%s", pszPath, OS_PATH_DELIMITER, pszFile );
if( access( ( const char * ) pszCfg, HB_ACCESS_FLAG ) == 0 )
{
bFound = TRUE;
break;
}
}
}
}
/* If not found, make sure to return a NULL string */
if( ! bFound )
*pszCfg = '\0';
return ( char * ) pszCfg;
}
/* Builds platform dependant object module from Harbour C output */
void hb_compGenCObj( HB_COMP_DECL, PHB_FNAME pFileName )
{
@@ -48,20 +100,15 @@ void hb_compGenCObj( HB_COMP_DECL, PHB_FNAME pFileName )
char szOptions[ HB_CFG_LINE_LEN + 1 ] = "";
char szCommandLine[ HB_CFG_LINE_LEN * 2 + 1 ];
char szOutPath[ _POSIX_PATH_MAX + 1 ] = "\0";
char pszTemp[ _POSIX_PATH_MAX + 1 ] = "";
#if defined( HOST_OS_UNIX_COMPATIBLE )
char szDefaultUnixPath[ _POSIX_PATH_MAX + 1 ] = "/etc:/usr/local/etc";
char * pszEnv = szDefaultUnixPath;
#define HB_NULL_STR " > /dev/null"
#define HB_ACCESS_FLAG F_OK
char * pszEnv = hb_strdup( "/etc:/usr/local/etc" );
#elif defined( OS_DOS_COMPATIBLE )
char * pszEnv = hb_getenv( "PATH" );
#define HB_NULL_STR " >nul"
#define HB_ACCESS_FLAG 0
#else
char * pszEnv = NULL;
#endif
FILE * yyc;
char * pszCfg;
FILE * filecfg;
BOOL bVerbose = FALSE; /* Don't show C compiler messages (default). */
BOOL bDelTmp = TRUE; /* Delete intermediate C file (default). */
int iSuccess;
@@ -78,27 +125,18 @@ void hb_compGenCObj( HB_COMP_DECL, PHB_FNAME pFileName )
/* Begin second pass */
/* Set up things */
/* Grab space */
pszCfg = ( char * ) hb_xgrab( _POSIX_PATH_MAX + 1 );
if( pszEnv && pszEnv[ 0 ] != '\0' && *hb_searchpath( HB_CFG_FILENAME, pszEnv, pszCfg ) )
if( pszEnv && *hb_searchpath( HB_CFG_FILENAME, pszEnv, pszTemp ) )
{
yyc = fopen( pszCfg, "rt" );
if( ! yyc )
filecfg = fopen( pszTemp, "rt" );
if( ! filecfg )
{
#if 0
/* QUESTION: Add a new error to Harbour ?
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_OPEN_CFG, szFileName, NULL );
*/
#else
printf( "\nError: Can't find %s file.\n", HB_CFG_FILENAME );
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_OPEN_CFG, szFileName, NULL );
if( pszEnv )
hb_xfree( ( void * ) pszEnv );
return;
#endif
}
while( fgets( szLine, HB_CFG_LINE_LEN, yyc ) != NULL )
while( fgets( szLine, HB_CFG_LINE_LEN, filecfg ) != NULL )
{
ULONG ulLen;
char * szStr = szLine;
@@ -117,55 +155,49 @@ void hb_compGenCObj( HB_COMP_DECL, PHB_FNAME pFileName )
/* TODO: Check for comments within macros, i.e: CC=bcc32 #comment */
if( *szStr )
{
szToken = strchr( szStr, '=' );
if( szToken )
{
szToken = strchr( szStr, '=' );
if( szToken )
*szToken++ = '\0';
if ( *szToken )
{
*szToken++ = '\0';
if ( *szToken )
/* Checks compiler name */
if( ! hb_stricmp( szStr, "CC" ) )
{
/* Checks compiler name */
if( ! hb_stricmp( szStr, "CC" ) )
{
snprintf( szCompiler, sizeof( szCompiler ), "%s", szToken );
}
/* Checks optional switches */
else if( ! hb_stricmp( szStr, "CFLAGS" ) )
{
snprintf( szOptions, sizeof( szCompiler ), "%s", szToken );
}
/* Wanna see C compiler output ? */
else if( ! hb_stricmp( szStr, "VERBOSE" ) )
{
if( ! hb_stricmp( szToken, "YES" ) )
bVerbose = TRUE;
}
/* Delete intermediate C file ? */
else if( ! hb_stricmp( szStr, "DELTMP" ) )
{
if( ! hb_stricmp( szToken, "NO" ) )
bDelTmp = FALSE;
}
snprintf( szCompiler, sizeof( szCompiler ), "%s", szToken );
}
/* Checks optional switches */
else if( ! hb_stricmp( szStr, "CFLAGS" ) )
{
snprintf( szOptions, sizeof( szCompiler ), "%s", szToken );
}
/* Wanna see C compiler output ? */
else if( ! hb_stricmp( szStr, "VERBOSE" ) )
{
if( ! hb_stricmp( szToken, "YES" ) )
bVerbose = TRUE;
}
/* Delete intermediate C file ? */
else if( ! hb_stricmp( szStr, "DELTMP" ) )
{
if( ! hb_stricmp( szToken, "NO" ) )
bDelTmp = FALSE;
}
}
}
}
}
fclose( yyc );
fclose( filecfg );
}
#if defined( OS_DOS_COMPATIBLE )
{
if( pszEnv )
hb_xfree( ( void * ) pszEnv );
}
#endif
if( pszEnv )
hb_xfree( ( void * ) pszEnv );
if( ! HB_COMP_PARAM->fQuiet )
{
printf( "Building object module output for \'%s\'...", szFileName );
printf( "Building object module output for '%s'...", szFileName );
fflush( stdout );
}
@@ -173,7 +205,6 @@ void hb_compGenCObj( HB_COMP_DECL, PHB_FNAME pFileName )
if( HB_COMP_PARAM->pOutPath )
{
PHB_FNAME pOut = hb_fsFNameSplit( ( char * ) szFileName );
char pszTemp[ _POSIX_PATH_MAX + 1 ] = "";
if( HB_COMP_PARAM->pOutPath->szPath )
pOut->szPath = HB_COMP_PARAM->pOutPath->szPath;
@@ -208,7 +239,7 @@ void hb_compGenCObj( HB_COMP_DECL, PHB_FNAME pFileName )
}
else
{
hb_strncat( szCommandLine, HB_NULL_STR, sizeof( szCommandLine ) );
hb_strncat( szCommandLine, HB_NULL_STR, sizeof( szCommandLine ) - 1 );
}
/* Compile it! */
@@ -231,46 +262,4 @@ void hb_compGenCObj( HB_COMP_DECL, PHB_FNAME pFileName )
{
printf( "\nError: No compiler defined in %s\n", HB_CFG_FILENAME );
}
if( pszCfg )
hb_xfree( pszCfg );
}
static char * hb_searchpath( const char * pszFile, char * pszEnv, char * pszCfg )
{
char * pszPath;
char pszDelim[2] = { OS_PATH_LIST_SEPARATOR, '\0'};
BOOL bFound = FALSE;
/* Check current dir first */
if( access( ( const char * ) pszFile, HB_ACCESS_FLAG ) == 0 )
{
snprintf( pszCfg, _POSIX_PATH_MAX + 1, "%s", pszFile );
return ( char * ) pszFile;
}
else
{
/* Check if pszFile exists somewhere in the path */
pszPath = strtok( pszEnv, pszDelim );
if( pszPath )
{
while( pszPath )
{
snprintf( pszCfg, _POSIX_PATH_MAX + 1, "%s%c%s", pszPath, OS_PATH_DELIMITER, pszFile );
if( access( ( const char * ) pszCfg, HB_ACCESS_FLAG ) == 0 )
{
bFound = TRUE;
break;
}
else
pszPath = strtok( NULL, pszDelim );
}
}
}
/* If not found, make sure to return a NULL string */
if( ! bFound )
snprintf( pszCfg, _POSIX_PATH_MAX + 1, "%s", "" );
return ( char * ) pszCfg;
}

View File

@@ -3306,11 +3306,30 @@ void hb_compGenPushDate( HB_LONG lNumber, HB_COMP_DECL )
/* generates the pcode to push a string on the virtual machine stack */
void hb_compGenPushString( char * szText, ULONG ulStrLen, HB_COMP_DECL )
{
if( ulStrLen > 255 )
hb_compGenPCode3( HB_P_PUSHSTR, HB_LOBYTE( ulStrLen ), HB_HIBYTE( ulStrLen ), HB_COMP_PARAM );
if( HB_COMP_PARAM->iHidden )
{
--ulStrLen;
szText = hb_compEncodeString( HB_COMP_PARAM->iHidden, szText, &ulStrLen );
hb_compGenPCode4( HB_P_PUSHSTRHIDDEN, ( BYTE ) HB_COMP_PARAM->iHidden,
HB_LOBYTE( ulStrLen ), HB_HIBYTE( ulStrLen ), HB_COMP_PARAM );
hb_compGenPCodeN( ( BYTE * ) szText, ulStrLen, HB_COMP_PARAM );
hb_xfree( szText );
}
else
hb_compGenPCode2( HB_P_PUSHSTRSHORT, ( BYTE ) ulStrLen, HB_COMP_PARAM );
hb_compGenPCodeN( ( BYTE * ) szText, ulStrLen, HB_COMP_PARAM );
{
if( ulStrLen > UINT24_MAX )
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_STRING_TOO_LONG, NULL, NULL );
else
{
if( ulStrLen > USHRT_MAX )
hb_compGenPCode4( HB_P_PUSHSTRLARGE, HB_LOBYTE( ulStrLen ), HB_HIBYTE( ulStrLen ), HB_ULBYTE( ulStrLen ), HB_COMP_PARAM );
else if( ulStrLen > UCHAR_MAX )
hb_compGenPCode3( HB_P_PUSHSTR, HB_LOBYTE( ulStrLen ), HB_HIBYTE( ulStrLen ), HB_COMP_PARAM );
else
hb_compGenPCode2( HB_P_PUSHSTRSHORT, ( BYTE ) ulStrLen, HB_COMP_PARAM );
hb_compGenPCodeN( ( BYTE * ) szText, ulStrLen, HB_COMP_PARAM );
}
}
}
/* generates the pcode to push a symbol on the virtual machine stack */
@@ -3500,7 +3519,7 @@ static void hb_compOptimizeFrames( HB_COMP_DECL, PFUNCTION pFunc )
pFunc->pCode[ 3 ] == HB_P_SFRAME )
{
PVAR pLocal;
int iLocals = 0;
int iLocals = 0, iOffset = 0;
BOOL bSkipFRAME;
BOOL bSkipSFRAME;
@@ -3512,29 +3531,6 @@ static void hb_compOptimizeFrames( HB_COMP_DECL, PFUNCTION pFunc )
iLocals++;
}
if( iLocals || pFunc->wParamCount )
{
/* Parameters declared with PARAMETERS statement are not
* placed in the local variable list.
*/
if( pFunc->bFlags & FUN_USES_LOCAL_PARAMS )
iLocals -= pFunc->wParamCount;
/* TODO: generate error when iLocals > 255 or add new
* HB_P_LARGE[V]FRAME pcode(s) and replace current
* pcode frame with the new one moving the pcode.
*/
pFunc->pCode[ 1 ] = ( BYTE )( iLocals );
pFunc->pCode[ 2 ] = ( BYTE )( pFunc->wParamCount );
bSkipFRAME = FALSE;
}
else
/* Skip LOCALs frame only when function is not declared with
* variable number of parameters (HB_P_VFRAME)
*/
bSkipFRAME = pFunc->pCode[ 0 ] == HB_P_FRAME;
if( pFunc->bFlags & FUN_USES_STATICS )
{
hb_compSymbolFind( HB_COMP_PARAM, HB_COMP_PARAM->pInitFunc->szName, &w, HB_SYM_FUNCNAME );
@@ -3545,22 +3541,61 @@ static void hb_compOptimizeFrames( HB_COMP_DECL, PFUNCTION pFunc )
else
bSkipSFRAME = TRUE;
if( iLocals || pFunc->wParamCount )
{
/* Parameters declared with PARAMETERS statement are not
* placed in the local variable list.
*/
if( pFunc->bFlags & FUN_USES_LOCAL_PARAMS )
iLocals -= pFunc->wParamCount;
if( iLocals > 255 )
{
/* more then 255 local variables,
* make a room for HB_P_LARGE[V]FRAME
*/
hb_compGenPCode1( 0, HB_COMP_PARAM );
memmove( pFunc->pCode + 4, pFunc->pCode + 3, pFunc->lPCodePos - 4 );
pFunc->pCode[ 0 ] = pFunc->pCode[ 0 ] == HB_P_FRAME ?
HB_P_LARGEFRAME : HB_P_LARGEVFRAME;
pFunc->pCode[ 1 ] = HB_LOBYTE( iLocals );
pFunc->pCode[ 2 ] = HB_HIBYTE( iLocals );
pFunc->pCode[ 3 ] = ( BYTE )( pFunc->wParamCount );
iOffset = 1;
}
else
{
pFunc->pCode[ 1 ] = ( BYTE )( iLocals );
pFunc->pCode[ 2 ] = ( BYTE )( pFunc->wParamCount );
}
bSkipFRAME = FALSE;
}
else
/* Skip LOCALs frame only when function is not declared with
* variable number of parameters (HB_P_VFRAME)
*/
bSkipFRAME = pFunc->pCode[ 0 ] == HB_P_FRAME;
/* Remove the frame pcodes if they are not needed */
if( bSkipFRAME && bSkipSFRAME )
if( bSkipFRAME )
{
pFunc->lPCodePos -= 6;
memmove( pFunc->pCode, pFunc->pCode + 6, pFunc->lPCodePos );
}
else if( bSkipFRAME )
{
pFunc->lPCodePos -= 3;
memmove( pFunc->pCode, pFunc->pCode + 3, pFunc->lPCodePos );
if( bSkipSFRAME )
{
pFunc->lPCodePos -= 6;
memmove( pFunc->pCode, pFunc->pCode + 6, pFunc->lPCodePos );
}
else
{
pFunc->lPCodePos -= 3;
memmove( pFunc->pCode, pFunc->pCode + 3, pFunc->lPCodePos );
}
}
else if( bSkipSFRAME )
{
pFunc->lPCodePos -= 3;
memmove( pFunc->pCode + 3, pFunc->pCode + 6, pFunc->lPCodePos - 3 );
memmove( pFunc->pCode + 3 + iOffset, pFunc->pCode + 6 + iOffset,
pFunc->lPCodePos - 3 - iOffset );
}
}
}
@@ -4118,7 +4153,7 @@ void hb_compCodeBlockEnd( HB_COMP_DECL )
{
PFUNCTION pCodeblock; /* pointer to the current codeblock */
PFUNCTION pFunc;/* pointer to a function that owns a codeblock */
USHORT wSize;
ULONG ulSize;
USHORT wLocals = 0; /* number of referenced local variables */
USHORT wLocalsCnt, wLocalsLen;
USHORT wPos;
@@ -4156,28 +4191,37 @@ void hb_compCodeBlockEnd( HB_COMP_DECL )
while( pVar )
{
if( HB_COMP_PARAM->fDebugInfo )
wLocalsLen += (4 + strlen(pVar->szName));
wLocalsLen += 4 + strlen( pVar->szName );
pVar = pVar->pNext;
++wLocals;
}
wLocalsCnt = wLocals;
/* NOTE: 2 = HB_P_PUSHBLOCK + BYTE( size ) */
wSize = ( USHORT ) pCodeblock->lPCodePos + 2;
ulSize = pCodeblock->lPCodePos + 2;
if( HB_COMP_PARAM->fDebugInfo )
{
wSize += (3 + strlen( hb_pp_fileName( HB_COMP_PARAM->pLex->pPP ) ) + strlen( pFunc->szName ));
wSize += wLocalsLen;
ulSize += 3 + strlen( hb_pp_fileName( HB_COMP_PARAM->pLex->pPP ) ) + strlen( pFunc->szName );
ulSize += wLocalsLen;
}
if( wSize <= 255 && pCodeblock->wParamCount == 0 && wLocals == 0 )
if( ulSize <= 255 && pCodeblock->wParamCount == 0 && wLocals == 0 )
{
hb_compGenPCode2( HB_P_PUSHBLOCKSHORT, ( BYTE ) wSize, HB_COMP_PARAM );
/* NOTE: 2 = HB_P_PUSHBLOCK + BYTE( size ) */
hb_compGenPCode2( HB_P_PUSHBLOCKSHORT, ( BYTE ) ulSize, HB_COMP_PARAM );
}
else
{
/* NOTE: 8 = HB_P_PUSHBLOCK + USHORT( size ) + USHORT( wParams ) + USHORT( wLocals ) + _ENDBLOCK */
wSize += (5+ wLocals * 2);
hb_compGenPCode3( HB_P_PUSHBLOCK, HB_LOBYTE( wSize ), HB_HIBYTE( wSize ), HB_COMP_PARAM );
ulSize += 5 + wLocals * 2;
if( ulSize <= USHRT_MAX )
hb_compGenPCode3( HB_P_PUSHBLOCK, HB_LOBYTE( ulSize ), HB_HIBYTE( ulSize ), HB_COMP_PARAM );
else if( ulSize < UINT24_MAX )
{
++ulSize;
hb_compGenPCode4( HB_P_PUSHBLOCKLARGE, HB_LOBYTE( ulSize ), HB_HIBYTE( ulSize ), HB_ULBYTE( ulSize ), HB_COMP_PARAM );
}
else
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_BLOCK_TOO_BIG, NULL, NULL );
/* generate the number of local parameters */
hb_compGenPCode2( HB_LOBYTE( pCodeblock->wParamCount ), HB_HIBYTE( pCodeblock->wParamCount ), HB_COMP_PARAM );

View File

@@ -1663,9 +1663,15 @@ ForNext : FOR LValue ForAssign Expression /* 1 2 3 4 */
iStep = 1;
}
if( iStep && ( iLocal = hb_compLocalGetPos( HB_COMP_PARAM, hb_compExprAsSymbol($<asExpr>2) ) ) > 0 && iLocal < 256 )
if( iStep && ( iLocal = hb_compLocalGetPos( HB_COMP_PARAM, hb_compExprAsSymbol($<asExpr>2) ) ) > 0 )
{
hb_compGenPCode4( HB_P_LOCALNEARADDINT, ( BYTE ) iLocal, HB_LOBYTE( iStep ), HB_HIBYTE( iStep ), HB_COMP_PARAM );
BYTE buffer[ 5 ];
buffer[ 0 ] = HB_P_LOCALADDINT;
buffer[ 1 ] = HB_LOBYTE( iLocal );
buffer[ 2 ] = HB_HIBYTE( iLocal );
buffer[ 3 ] = HB_LOBYTE( iStep );
buffer[ 4 ] = HB_HIBYTE( iStep );
hb_compGenPCodeN( buffer, 5, HB_COMP_PARAM );
}
else if( $<asExpr>8 )
{

View File

@@ -1144,14 +1144,14 @@ static const yytype_uint16 yyrline[] =
1518, 1520, 1518, 1529, 1530, 1533, 1537, 1541, 1544, 1550,
1554, 1560, 1560, 1563, 1564, 1572, 1573, 1572, 1584, 1585,
1584, 1597, 1597, 1597, 1599, 1599, 1604, 1609, 1603, 1621,
1624, 1625, 1629, 1640, 1645, 1628, 1705, 1706, 1709, 1710,
1713, 1714, 1715, 1716, 1719, 1720, 1723, 1724, 1727, 1728,
1732, 1738, 1747, 1731, 1767, 1768, 1772, 1771, 1784, 1791,
1799, 1798, 1808, 1809, 1817, 1817, 1820, 1820, 1823, 1825,
1828, 1828, 1828, 1832, 1834, 1842, 1832, 1863, 1864, 1864,
1865, 1865, 1868, 1878, 1895, 1896, 1897, 1900, 1902, 1904,
1909, 1916, 1917, 1918, 1919, 1920, 1923, 1924, 1925, 1926,
1927, 1928, 1929, 1933, 1932, 1944, 1947, 1948
1624, 1625, 1629, 1640, 1645, 1628, 1711, 1712, 1715, 1716,
1719, 1720, 1721, 1722, 1725, 1726, 1729, 1730, 1733, 1734,
1738, 1744, 1753, 1737, 1773, 1774, 1778, 1777, 1790, 1797,
1805, 1804, 1814, 1815, 1823, 1823, 1826, 1826, 1829, 1831,
1834, 1834, 1834, 1838, 1840, 1848, 1838, 1869, 1870, 1870,
1871, 1871, 1874, 1884, 1901, 1902, 1903, 1906, 1908, 1910,
1915, 1922, 1923, 1924, 1925, 1926, 1929, 1930, 1931, 1932,
1933, 1934, 1935, 1939, 1938, 1950, 1953, 1954
};
#endif
@@ -7633,9 +7633,15 @@ yyreduce:
iStep = 1;
}
if( iStep && ( iLocal = hb_compLocalGetPos( HB_COMP_PARAM, hb_compExprAsSymbol((yyvsp[(2) - (12)].asExpr)) ) ) > 0 && iLocal < 256 )
if( iStep && ( iLocal = hb_compLocalGetPos( HB_COMP_PARAM, hb_compExprAsSymbol((yyvsp[(2) - (12)].asExpr)) ) ) > 0 )
{
hb_compGenPCode4( HB_P_LOCALNEARADDINT, ( BYTE ) iLocal, HB_LOBYTE( iStep ), HB_HIBYTE( iStep ), HB_COMP_PARAM );
BYTE buffer[ 5 ];
buffer[ 0 ] = HB_P_LOCALADDINT;
buffer[ 1 ] = HB_LOBYTE( iLocal );
buffer[ 2 ] = HB_HIBYTE( iLocal );
buffer[ 3 ] = HB_LOBYTE( iStep );
buffer[ 4 ] = HB_HIBYTE( iStep );
hb_compGenPCodeN( buffer, 5, HB_COMP_PARAM );
}
else if( (yyvsp[(8) - (12)].asExpr) )
{
@@ -7673,67 +7679,67 @@ yyreduce:
break;
case 698:
#line 1709 "harbour.y"
#line 1715 "harbour.y"
{ (yyval.asExpr) = NULL; ;}
break;
case 699:
#line 1710 "harbour.y"
#line 1716 "harbour.y"
{ (yyval.asExpr) = hb_compExprReduce( (yyvsp[(2) - (2)].asExpr), HB_COMP_PARAM ); ;}
break;
case 700:
#line 1713 "harbour.y"
#line 1719 "harbour.y"
{ hb_compLinePush( HB_COMP_PARAM ); --HB_COMP_PARAM->wForCounter; ;}
break;
case 701:
#line 1714 "harbour.y"
#line 1720 "harbour.y"
{ hb_compLinePush( HB_COMP_PARAM ); --HB_COMP_PARAM->wForCounter; ;}
break;
case 702:
#line 1715 "harbour.y"
#line 1721 "harbour.y"
{ hb_compLinePush( HB_COMP_PARAM ); --HB_COMP_PARAM->wForCounter; ;}
break;
case 703:
#line 1716 "harbour.y"
#line 1722 "harbour.y"
{ hb_compLinePush( HB_COMP_PARAM ); --HB_COMP_PARAM->wForCounter; ;}
break;
case 704:
#line 1719 "harbour.y"
#line 1725 "harbour.y"
{ (yyval.asExpr) = hb_compExprNewVarRef( (yyvsp[(1) - (1)].string), HB_COMP_PARAM ); ;}
break;
case 705:
#line 1720 "harbour.y"
#line 1726 "harbour.y"
{ (yyval.asExpr) = hb_compExprNewRef( (yyvsp[(1) - (1)].asExpr), HB_COMP_PARAM ); ;}
break;
case 706:
#line 1723 "harbour.y"
#line 1729 "harbour.y"
{ (yyval.asExpr) = hb_compExprNewArgList( (yyvsp[(1) - (1)].asExpr), HB_COMP_PARAM ); ;}
break;
case 707:
#line 1724 "harbour.y"
#line 1730 "harbour.y"
{ (yyval.asExpr) = hb_compExprAddListExpr( (yyvsp[(1) - (3)].asExpr), (yyvsp[(3) - (3)].asExpr) ); ;}
break;
case 708:
#line 1727 "harbour.y"
#line 1733 "harbour.y"
{ (yyval.asExpr) = hb_compExprNewArgList( (yyvsp[(1) - (1)].asExpr), HB_COMP_PARAM ); ;}
break;
case 709:
#line 1728 "harbour.y"
#line 1734 "harbour.y"
{ (yyval.asExpr) = hb_compExprAddListExpr( (yyvsp[(1) - (3)].asExpr), (yyvsp[(3) - (3)].asExpr) ); ;}
break;
case 710:
#line 1732 "harbour.y"
#line 1738 "harbour.y"
{
++HB_COMP_PARAM->wForCounter; /* 5 */
hb_compLinePush( HB_COMP_PARAM );
@@ -7742,7 +7748,7 @@ yyreduce:
break;
case 711:
#line 1738 "harbour.y"
#line 1744 "harbour.y"
{
/* 7
*/
@@ -7754,7 +7760,7 @@ yyreduce:
break;
case 712:
#line 1747 "harbour.y"
#line 1753 "harbour.y"
{
/* 9
*/
@@ -7763,7 +7769,7 @@ yyreduce:
break;
case 713:
#line 1753 "harbour.y"
#line 1759 "harbour.y"
{
hb_compLoopHere( HB_COMP_PARAM );
hb_compEnumNext( HB_COMP_PARAM, (yyvsp[(2) - (10)].asExpr), (yyvsp[(6) - (10)].iNumber) );
@@ -7779,17 +7785,17 @@ yyreduce:
break;
case 714:
#line 1767 "harbour.y"
#line 1773 "harbour.y"
{ (yyval.iNumber) = 1; ;}
break;
case 715:
#line 1768 "harbour.y"
#line 1774 "harbour.y"
{ (yyval.iNumber) = -1; ;}
break;
case 716:
#line 1772 "harbour.y"
#line 1778 "harbour.y"
{
hb_compLoopStart( HB_COMP_PARAM );
hb_compSwitchStart( HB_COMP_PARAM );
@@ -7798,7 +7804,7 @@ yyreduce:
break;
case 717:
#line 1779 "harbour.y"
#line 1785 "harbour.y"
{
hb_compSwitchEnd( HB_COMP_PARAM );
hb_compLoopEnd( HB_COMP_PARAM );
@@ -7806,14 +7812,14 @@ yyreduce:
break;
case 718:
#line 1786 "harbour.y"
#line 1792 "harbour.y"
{
hb_compGenPCode1( HB_P_POP, HB_COMP_PARAM );
;}
break;
case 719:
#line 1792 "harbour.y"
#line 1798 "harbour.y"
{
--HB_COMP_PARAM->wSwitchCounter;
HB_COMP_PARAM->functions.pLast->bFlags &= ~ ( FUN_WITH_RETURN | FUN_BREAK_CODE );
@@ -7821,26 +7827,26 @@ yyreduce:
break;
case 720:
#line 1799 "harbour.y"
#line 1805 "harbour.y"
{ ++HB_COMP_PARAM->wSwitchCounter;
hb_compLinePush( HB_COMP_PARAM );
;}
break;
case 721:
#line 1803 "harbour.y"
#line 1809 "harbour.y"
{
hb_compExprDelete( hb_compExprGenPush( (yyvsp[(3) - (4)].asExpr), HB_COMP_PARAM ), HB_COMP_PARAM );
;}
break;
case 722:
#line 1808 "harbour.y"
#line 1814 "harbour.y"
{ ;}
break;
case 723:
#line 1809 "harbour.y"
#line 1815 "harbour.y"
{
if( (yyvsp[(2) - (2)].lNumber) > 0 )
{
@@ -7850,32 +7856,32 @@ yyreduce:
break;
case 724:
#line 1817 "harbour.y"
#line 1823 "harbour.y"
{ hb_compSwitchAdd( HB_COMP_PARAM, (yyvsp[(2) - (2)].asExpr) ); hb_compLinePush( HB_COMP_PARAM ); ;}
break;
case 726:
#line 1820 "harbour.y"
#line 1826 "harbour.y"
{ hb_compSwitchAdd( HB_COMP_PARAM, (yyvsp[(3) - (3)].asExpr) ); hb_compLinePush( HB_COMP_PARAM ); ;}
break;
case 730:
#line 1828 "harbour.y"
#line 1834 "harbour.y"
{ hb_compSwitchAdd( HB_COMP_PARAM, NULL ); hb_compLinePush( HB_COMP_PARAM ); ;}
break;
case 731:
#line 1828 "harbour.y"
#line 1834 "harbour.y"
{ HB_COMP_PARAM->functions.pLast->bFlags &= ~ FUN_BREAK_CODE; ;}
break;
case 733:
#line 1832 "harbour.y"
#line 1838 "harbour.y"
{ ++HB_COMP_PARAM->wSeqCounter; (yyval.lNumber) = hb_compSequenceBegin( HB_COMP_PARAM ); ;}
break;
case 734:
#line 1834 "harbour.y"
#line 1840 "harbour.y"
{
/* Set jump address for HB_P_SEQBEGIN opcode - this address
* will be used in BREAK code if there is no RECOVER clause
@@ -7886,7 +7892,7 @@ yyreduce:
break;
case 735:
#line 1842 "harbour.y"
#line 1848 "harbour.y"
{
/* Replace END address with RECOVER address in
* HB_P_SEQBEGIN opcode if there is RECOVER clause
@@ -7897,7 +7903,7 @@ yyreduce:
break;
case 736:
#line 1850 "harbour.y"
#line 1856 "harbour.y"
{
/* Fix END address
* There is no line number after HB_P_SEQEND in case no
@@ -7912,22 +7918,22 @@ yyreduce:
break;
case 737:
#line 1863 "harbour.y"
#line 1869 "harbour.y"
{ (yyval.lNumber) = 0; ;}
break;
case 738:
#line 1864 "harbour.y"
#line 1870 "harbour.y"
{ (yyval.lNumber) = (yyvsp[(1) - (2)].lNumber); ;}
break;
case 740:
#line 1865 "harbour.y"
#line 1871 "harbour.y"
{ (yyval.lNumber) = (yyvsp[(1) - (2)].lNumber); ;}
break;
case 742:
#line 1869 "harbour.y"
#line 1875 "harbour.y"
{
HB_COMP_PARAM->functions.pLast->bFlags &= ~ FUN_BREAK_CODE;
(yyval.lNumber) = HB_COMP_PARAM->functions.pLast->lPCodePos;
@@ -7938,7 +7944,7 @@ yyreduce:
break;
case 743:
#line 1879 "harbour.y"
#line 1885 "harbour.y"
{
HB_COMP_PARAM->functions.pLast->bFlags &= ~ FUN_BREAK_CODE;
(yyval.lNumber) = HB_COMP_PARAM->functions.pLast->lPCodePos;
@@ -7950,32 +7956,32 @@ yyreduce:
break;
case 744:
#line 1895 "harbour.y"
#line 1901 "harbour.y"
{ (yyval.asExpr) = hb_compExprNewFunName( (yyvsp[(1) - (1)].string), HB_COMP_PARAM ); hb_compAutoOpenAdd( HB_COMP_PARAM, (yyvsp[(1) - (1)].string) ); ;}
break;
case 745:
#line 1896 "harbour.y"
#line 1902 "harbour.y"
{ (yyval.asExpr) = (yyvsp[(1) - (1)].asExpr); ;}
break;
case 746:
#line 1897 "harbour.y"
#line 1903 "harbour.y"
{ (yyval.asExpr) = (yyvsp[(1) - (1)].asExpr); ;}
break;
case 747:
#line 1901 "harbour.y"
#line 1907 "harbour.y"
{ (yyval.asExpr) = hb_compExprNewFunCall( (yyvsp[(2) - (2)].asExpr), NULL, HB_COMP_PARAM ); ;}
break;
case 748:
#line 1903 "harbour.y"
#line 1909 "harbour.y"
{ (yyval.asExpr) = hb_compExprNewFunCall( (yyvsp[(2) - (4)].asExpr), (yyvsp[(4) - (4)].asExpr), HB_COMP_PARAM ); ;}
break;
case 749:
#line 1905 "harbour.y"
#line 1911 "harbour.y"
{
/* DOIDENT is the only one identifier which can be returned in lower letters */
hb_compAutoOpenAdd( HB_COMP_PARAM, (yyvsp[(1) - (1)].string) ); (yyval.asExpr) = hb_compExprNewFunCall( hb_compExprNewFunName( hb_compIdentifierNew( HB_COMP_PARAM, hb_strupr( hb_strdup( (yyvsp[(1) - (1)].string) ) ), HB_IDENT_FREE ), HB_COMP_PARAM ), NULL, HB_COMP_PARAM );
@@ -7983,7 +7989,7 @@ yyreduce:
break;
case 750:
#line 1910 "harbour.y"
#line 1916 "harbour.y"
{
/* DOIDENT is the only one identifier which can be returned in lower letters */
hb_compAutoOpenAdd( HB_COMP_PARAM, (yyvsp[(1) - (3)].string) ); (yyval.asExpr) = hb_compExprNewFunCall( hb_compExprNewFunName( hb_compIdentifierNew( HB_COMP_PARAM, hb_strupr( hb_strdup( (yyvsp[(1) - (3)].string) ) ), HB_IDENT_FREE ), HB_COMP_PARAM ), (yyvsp[(3) - (3)].asExpr), HB_COMP_PARAM );
@@ -7991,67 +7997,67 @@ yyreduce:
break;
case 751:
#line 1916 "harbour.y"
#line 1922 "harbour.y"
{ (yyval.asExpr) = hb_compExprAddListExpr( hb_compExprNewArgList( hb_compExprNewNil( HB_COMP_PARAM ), HB_COMP_PARAM ), hb_compExprNewNil( HB_COMP_PARAM ) ); ;}
break;
case 752:
#line 1917 "harbour.y"
#line 1923 "harbour.y"
{ (yyval.asExpr) = hb_compExprAddListExpr( hb_compExprNewArgList( hb_compExprNewNil( HB_COMP_PARAM ), HB_COMP_PARAM ), (yyvsp[(2) - (2)].asExpr) ); ;}
break;
case 753:
#line 1918 "harbour.y"
#line 1924 "harbour.y"
{ (yyval.asExpr) = hb_compExprNewArgList( (yyvsp[(1) - (1)].asExpr), HB_COMP_PARAM ); ;}
break;
case 754:
#line 1919 "harbour.y"
#line 1925 "harbour.y"
{ (yyval.asExpr) = hb_compExprAddListExpr( (yyvsp[(1) - (2)].asExpr), hb_compExprNewNil( HB_COMP_PARAM ) ); ;}
break;
case 755:
#line 1920 "harbour.y"
#line 1926 "harbour.y"
{ (yyval.asExpr) = hb_compExprAddListExpr( (yyvsp[(1) - (3)].asExpr), (yyvsp[(3) - (3)].asExpr) ); ;}
break;
case 756:
#line 1923 "harbour.y"
#line 1929 "harbour.y"
{ (yyval.asExpr) = hb_compExprNewVarRef( (yyvsp[(1) - (1)].string), HB_COMP_PARAM ); ;}
break;
case 757:
#line 1924 "harbour.y"
#line 1930 "harbour.y"
{ (yyval.asExpr) = (yyvsp[(2) - (2)].asExpr); ;}
break;
case 758:
#line 1925 "harbour.y"
#line 1931 "harbour.y"
{ (yyval.asExpr) = hb_compExprNewVarRef( (yyvsp[(2) - (2)].string), HB_COMP_PARAM ); ;}
break;
case 759:
#line 1926 "harbour.y"
#line 1932 "harbour.y"
{ (yyval.asExpr) = (yyvsp[(1) - (1)].asExpr); ;}
break;
case 760:
#line 1927 "harbour.y"
#line 1933 "harbour.y"
{ (yyval.asExpr) = (yyvsp[(1) - (1)].asExpr); ;}
break;
case 761:
#line 1928 "harbour.y"
#line 1934 "harbour.y"
{ (yyval.asExpr) = hb_compExprNewRef( (yyvsp[(2) - (2)].asExpr), HB_COMP_PARAM ); ;}
break;
case 762:
#line 1929 "harbour.y"
#line 1935 "harbour.y"
{ (yyval.asExpr) = hb_compExprNewRef( (yyvsp[(2) - (2)].asExpr), HB_COMP_PARAM ); ;}
break;
case 763:
#line 1933 "harbour.y"
#line 1939 "harbour.y"
{
hb_compExprDelete( hb_compExprGenPush( (yyvsp[(2) - (3)].asExpr), HB_COMP_PARAM ), HB_COMP_PARAM );
hb_compGenPCode1( HB_P_WITHOBJECTSTART, HB_COMP_PARAM );
@@ -8060,7 +8066,7 @@ yyreduce:
break;
case 764:
#line 1940 "harbour.y"
#line 1946 "harbour.y"
{
--HB_COMP_PARAM->wWithObjectCnt;
hb_compGenPCode1( HB_P_WITHOBJECTEND, HB_COMP_PARAM );
@@ -8068,23 +8074,23 @@ yyreduce:
break;
case 765:
#line 1944 "harbour.y"
#line 1950 "harbour.y"
{ hb_compExprDelete( (yyvsp[(2) - (4)].asExpr), HB_COMP_PARAM ); ;}
break;
case 766:
#line 1947 "harbour.y"
#line 1953 "harbour.y"
{ HB_COMP_PARAM->fError = FALSE; ;}
break;
case 767:
#line 1948 "harbour.y"
#line 1954 "harbour.y"
{ HB_COMP_PARAM->fDontGenLineNum = TRUE; ;}
break;
/* Line 1267 of yacc.c. */
#line 8088 "harboury.c"
#line 8094 "harboury.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -8298,7 +8304,7 @@ yyreturn:
}
#line 1951 "harbour.y"
#line 1957 "harbour.y"
/*

View File

@@ -459,7 +459,20 @@ static PHB_CODETRACE_FUNC s_codeTraceFuncTable[ HB_P_LAST_PCODE ] =
hb_p_default, /* HB_P_MACROSEND */
hb_p_default, /* HB_P_PUSHOVARREF */
hb_p_default, /* HB_P_ARRAYPUSHREF */
hb_p_default /* HB_P_VFRAME */
hb_p_default, /* HB_P_VFRAME */
hb_p_default, /* HB_P_LARGEFRAME */
hb_p_default, /* HB_P_LARGEVFRAME */
hb_p_default, /* HB_P_PUSHSTRHIDDEN */
hb_p_default, /* HB_P_LOCALADDINT */
hb_p_default, /* HB_P_MODEQPOP */
hb_p_default, /* HB_P_EXPEQPOP */
hb_p_default, /* HB_P_MODEQ */
hb_p_default, /* HB_P_EXPEQ */
hb_p_default, /* HB_P_DUPLUNREF */
hb_p_default, /* HB_P_MPUSHBLOCKLARGE */
hb_p_default, /* HB_P_MPUSHSTRLARGE */
hb_p_default, /* HB_P_PUSHBLOCKLARGE */
hb_p_default /* HB_P_PUSHSTRLARGE */
};
void hb_compCodeTraceMarkDead( HB_COMP_DECL, PFUNCTION pFunc )

View File

@@ -75,6 +75,16 @@ static HB_FIX_FUNC( hb_p_endblock )
return 1;
}
static HB_FIX_FUNC( hb_p_pushblockshort )
{
HB_SYMBOL_UNUSED( pFunc );
HB_SYMBOL_UNUSED( lPCodePos );
++cargo->iNestedCodeblock;
return 2;
}
static HB_FIX_FUNC( hb_p_pushblock )
{
USHORT wVar;
@@ -82,7 +92,7 @@ static HB_FIX_FUNC( hb_p_pushblock )
++cargo->iNestedCodeblock;
wVar = HB_PCODE_MKUSHORT( &( pFunc->pCode[ lPCodePos + 5 ] ) );
wVar = HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 5 ] );
/* opcode + codeblock size + number of parameters + number of local variables */
lPCodePos += 7;
@@ -107,14 +117,36 @@ static HB_FIX_FUNC( hb_p_pushblock )
return (lPCodePos - ulStart);
}
static HB_FIX_FUNC( hb_p_pushblockshort )
static HB_FIX_FUNC( hb_p_pushblocklarge )
{
HB_SYMBOL_UNUSED( pFunc );
HB_SYMBOL_UNUSED( lPCodePos );
USHORT wVar;
ULONG ulStart = lPCodePos;
++cargo->iNestedCodeblock;
return 2;
wVar = HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 6 ] );
/* opcode + codeblock size + number of parameters + number of local variables */
lPCodePos += 8;
if( pFunc->wParamCount == 0 )
{
lPCodePos += wVar << 1;
}
else
{
/* fix local variable's reference */
while( wVar-- )
{
BYTE * pLocal = &( pFunc->pCode[ lPCodePos ] );
USHORT wLocal = HB_PCODE_MKUSHORT( pLocal );
wLocal += pFunc->wParamCount;
pLocal[ 0 ] = HB_LOBYTE( wLocal );
pLocal[ 1 ] = HB_HIBYTE( wLocal );
lPCodePos += 2;
}
}
return (lPCodePos - ulStart);
}
static HB_FIX_FUNC( hb_p_poplocal )
@@ -124,7 +156,6 @@ static HB_FIX_FUNC( hb_p_poplocal )
if( cargo->iNestedCodeblock == 0 )
{
HB_COMP_DECL = cargo->HB_COMP_PARAM;
BYTE * pVar = &pFunc->pCode[ lPCodePos + 1 ];
SHORT iVar = HB_PCODE_MKSHORT( pVar );
@@ -239,6 +270,33 @@ static HB_FIX_FUNC( hb_p_pushlocalnear )
return 2;
}
static HB_FIX_FUNC( hb_p_localaddint )
{
/* only local variables used outside of a codeblock need fixing
*/
if( cargo->iNestedCodeblock == 0 )
{
HB_COMP_DECL = cargo->HB_COMP_PARAM;
BYTE * pVar = &pFunc->pCode[ lPCodePos + 1 ];
SHORT iVar = HB_PCODE_MKSHORT( pVar );
iVar += pFunc->wParamCount;
if( HB_LIM_INT8( iVar ) && HB_COMP_ISSUPPORTED(HB_COMPFLAG_OPTJUMP) )
{
pVar[ 0 ] = HB_P_LOCALNEARADDINT;
pVar[ 1 ] = HB_LOBYTE( iVar );
hb_compNOOPfill( pFunc, lPCodePos, 1, FALSE, FALSE );
}
else
{
pVar[ 0 ] = HB_LOBYTE( iVar );
pVar[ 1 ] = HB_HIBYTE( iVar );
}
}
return 5;
}
static HB_FIX_FUNC( hb_p_localnearaddint )
{
/* only local variables used outside of a codeblock need fixing
@@ -650,7 +708,20 @@ static HB_FIX_FUNC_PTR s_fixlocals_table[] =
NULL, /* HB_P_MACROSEND */
NULL, /* HB_P_PUSHOVARREF */
NULL, /* HB_P_ARRAYPUSHREF */
NULL /* HB_P_VFRAME */
NULL, /* HB_P_VFRAME */
NULL, /* HB_P_LARGEFRAME */
NULL, /* HB_P_LARGEVFRAME */
NULL, /* HB_P_PUSHSTRHIDDEN */
hb_p_localaddint, /* HB_P_LOCALADDINT */
NULL, /* HB_P_MODEQPOP */
NULL, /* HB_P_EXPEQPOP */
NULL, /* HB_P_MODEQ */
NULL, /* HB_P_EXPEQ */
NULL, /* HB_P_DUPLUNREF */
NULL, /* HB_P_MPUSHBLOCKLARGE */
NULL, /* HB_P_MPUSHSTRLARGE */
hb_p_pushblocklarge, /* HB_P_PUSHBLOCKLARGE */
NULL /* HB_P_PUSHSTRLARGE */
};
void hb_compFixFuncPCode( HB_COMP_DECL, PFUNCTION pFunc )

View File

@@ -32,54 +32,54 @@
char * hb_comp_szErrors[] =
{
"Statement not allowed outside of procedure or function",
"Redefinition of procedure or function: \'%s\'",
"Duplicate variable declaration: \'%s\'",
"Redefinition of procedure or function: '%s'",
"Duplicate variable declaration: '%s'",
"%s declaration follows executable statement",
"Outer codeblock variable is out of reach: \'%s\'",
"Outer codeblock variable is out of reach: '%s'",
"Invalid numeric format '.'",
"Unterminated string: \'%s\'",
"Redefinition of predefined function %s: \'%s\'",
"Illegal variable \'%s\' initializer: \'%s\'",
"Unterminated string: '%s'",
"Redefinition of predefined function %s: '%s'",
"Illegal variable '%s' initializer: '%s'",
"ENDIF does not match IF",
"ENDDO does not match WHILE",
"ENDCASE does not match DO CASE",
"NEXT does not match FOR",
"ELSE does not match IF",
"ELSEIF does not match IF",
"Syntax error: \'%s\'",
"Syntax error: '%s'",
"Unclosed control structures",
"%s statement with no loop in sight",
"Syntax error: \'%s\' in: \'%s\'",
"Syntax error: '%s' in: '%s'",
"Incomplete statement: %s",
"Incorrect number of arguments: %s %s",
"Invalid lvalue: \'%s\'",
"Invalid use of \'@\' (pass by reference): \'%s\'",
"Invalid lvalue: '%s'",
"Invalid use of '@' (pass by reference): '%s'",
"Formal parameters already declared",
"Invalid %s from within of SEQUENCE code",
"Unterminated array index",
"Could not allocate %s byte(s)",
"Could not reallocate %s byte(s)",
"Freeing a NULL memory pointer",
"Syntax error: \"%s at \'%s\'\"",
"Syntax error: \"%s at '%s'\"",
"Jump offset too long",
"Can't create output file: \'%s\'",
"Can't create preprocessed output file: \'%s\'",
"Bad command line option: \'%s\'",
"Bad command line parameter: \'%s\'",
"Invalid filename: \'%s\'",
"Can't create output file: '%s'",
"Can't create preprocessed output file: '%s'",
"Bad command line option: '%s'",
"Bad command line parameter: '%s'",
"Invalid filename: '%s'",
"Mayhem in CASE handler",
"Operation not supported for this data type: \'%s\'",
"Invalid alias expression: \'%s\'",
"Invalid array index expression: \'%s\'",
"Bound error: \'%s\'",
"Macro of declared symbol: \'%s\'",
"Invalid selector in send: \'%s\'",
"ANNOUNCEd procedure \'%s\' must be a public symbol",
"Operation not supported for this data type: '%s'",
"Invalid alias expression: '%s'",
"Invalid array index expression: '%s'",
"Bound error: '%s'",
"Macro of declared symbol: '%s'",
"Invalid selector in send: '%s'",
"ANNOUNCEd procedure '%s' must be a public symbol",
"Jump PCode not found",
"CASE or OTHERWISE does not match DO CASE",
"Code block contains both macro and declared symbol references \'%s\'",
"Code block contains both macro and declared symbol references '%s'",
"GET contains complex macro",
"Unterminated inline block in function: \'%s\'",
"Unterminated inline block in function: '%s'",
"Too many inline blocks %s",
"Inline C requires C output generation, use -gc[n]",
"Too many local variables [%s] or parameters [%s]",
@@ -87,12 +87,15 @@ char * hb_comp_szErrors[] =
"Incorrect number of enumerate variables",
"CASE requires either numeric or string constant",
"String too long for SWITCH",
"Invalid date constant \'%s\'",
"Invalid date constant '%s'",
"Memory buffer overflow",
"Memory corruption detected",
"Implicit send operator with no WITH OBJECT in sight",
"Input buffer overflow",
"Unsupported output language option"
"Unsupported output language option",
"String too long",
"Code block size too big",
"Can't find %s file"
};
/* Table with parse warnings */
@@ -101,37 +104,37 @@ char * hb_comp_szErrors[] =
*/
char * hb_comp_szWarnings[] =
{
"1Ambiguous reference: \'%s\'",
"1Ambiguous reference, assuming memvar: \'%s\'",
"2Variable: \'%s\' declared but not used in function: \'%s\'",
"2Codeblock parameter: \'%s\' declared but not used in function: \'%s\'",
"1Ambiguous reference: '%s'",
"1Ambiguous reference, assuming memvar: '%s'",
"2Variable: '%s' declared but not used in function: '%s'",
"2Codeblock parameter: '%s' declared but not used in function: '%s'",
"1RETURN statement with no return value in function",
"1Procedure returns value",
"1Function \'%s\' does not end with RETURN statement",
"3Incompatible type in assignment to: \'%s\' expected: \'%s\'",
"3Incompatible operand type: \'%s\' expected: \'%s\'",
"3Incompatible operand types: \'%s\' and: \'%s\'",
"4Suspicious type in assignment to: \'%s\' expected: \'%s\'",
"4Suspicious operand type: \'unknown\' expected: \'%s\'",
"3Can\'t use array index with non-array",
"3Incompatible return type: \'%s\' expected: \'%s\'",
"4Suspicious return type: \'%s\' expected: \'%s\'",
"1Function '%s' does not end with RETURN statement",
"3Incompatible type in assignment to: '%s' expected: '%s'",
"3Incompatible operand type: '%s' expected: '%s'",
"3Incompatible operand types: '%s' and: '%s'",
"4Suspicious type in assignment to: '%s' expected: '%s'",
"4Suspicious operand type: 'unknown' expected: '%s'",
"3Can't use array index with non-array",
"3Incompatible return type: '%s' expected: '%s'",
"4Suspicious return type: '%s' expected: '%s'",
"3Invalid number of parameters: %s expected: %s",
"3Incompatible parameter: %s expected: \'%s\'",
"4Suspicious parameter: %s expected: \'%s\'",
"3Duplicate declaration of %s \'%s\'",
"3Function \'%s\' conflicting with its declaration",
"3Variable \'%s\' used but never initialized",
"3Value of Variable \'%s\' never used",
"3Incompatible type in assignment to declared array element expected: \'%s\'",
"4Suspicious type in assignment to declared array element expected: \'%s\'",
"3Class \'%s\' not known in declaration of \'%s\'",
"3Message \'%s\' not known in class \'%s\'",
"0Meaningless use of expression: \'%s\'",
"3Incompatible parameter: %s expected: '%s'",
"4Suspicious parameter: %s expected: '%s'",
"3Duplicate declaration of %s '%s'",
"3Function '%s' conflicting with its declaration",
"3Variable '%s' used but never initialized",
"3Value of Variable '%s' never used",
"3Incompatible type in assignment to declared array element expected: '%s'",
"4Suspicious type in assignment to declared array element expected: '%s'",
"3Class '%s' not known in declaration of '%s'",
"3Message '%s' not known in class '%s'",
"0Meaningless use of expression: '%s'",
"2Unreachable code",
"1Redundant \'ANNOUNCE %s\' statement ignored",
"0Duplicate variable \'%s\' in nested FOR loop",
"0Invalid variable \'%s\' for enumerator message"
"1Redundant 'ANNOUNCE %s' statement ignored",
"0Duplicate variable '%s' in nested FOR loop",
"0Invalid variable '%s' for enumerator message"
};
void hb_compGenError( HB_COMP_DECL, char * szErrors[], char cPrefix, int iError, const char * szError1, const char * szError2 )

View File

@@ -323,7 +323,20 @@ static PHB_LABEL_FUNC s_GenLabelFuncTable[ HB_P_LAST_PCODE ] =
NULL, /* HB_P_MACROSEND */
NULL, /* HB_P_PUSHOVARREF */
NULL, /* HB_P_ARRAYPUSHREF */
NULL /* HB_P_VFRAME */
NULL, /* HB_P_VFRAME */
NULL, /* HB_P_LARGEFRAME */
NULL, /* HB_P_LARGEVFRAME */
NULL, /* HB_P_PUSHSTRHIDDEN */
NULL, /* HB_P_LOCALADDINT */
NULL, /* HB_P_MODEQPOP */
NULL, /* HB_P_EXPEQPOP */
NULL, /* HB_P_MODEQ */
NULL, /* HB_P_EXPEQ */
NULL, /* HB_P_DUPLUNREF */
NULL, /* HB_P_MPUSHBLOCKLARGE */
NULL, /* HB_P_MPUSHSTRLARGE */
NULL, /* HB_P_PUSHBLOCKLARGE */
NULL /* HB_P_PUSHSTRLARGE */
};
void hb_compGenLabelTable( PFUNCTION pFunc, PHB_LABEL_INFO label_info )

View File

@@ -46,16 +46,28 @@
/*
* functions for variable size PCODE tracing
*/
static HB_PSIZE_FUNC( hb_p_pushstrshort )
{
HB_SYMBOL_UNUSED( cargo );
return 2 + pFunc->pCode[ lPCodePos + 1 ];
}
static HB_PSIZE_FUNC( hb_p_pushstr )
{
HB_SYMBOL_UNUSED( cargo );
return 3 + HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 1 ] );
}
static HB_PSIZE_FUNC( hb_p_pushstrshort )
static HB_PSIZE_FUNC( hb_p_pushstrlarge )
{
HB_SYMBOL_UNUSED( cargo );
return 2 + pFunc->pCode[ lPCodePos + 1 ];
return 4 + HB_PCODE_MKUINT24( &pFunc->pCode[ lPCodePos + 1 ] );
}
static HB_PSIZE_FUNC( hb_p_pushstrhidden )
{
HB_SYMBOL_UNUSED( cargo );
return 4 + HB_PCODE_MKUSHORT( &pFunc->pCode[ lPCodePos + 2 ] );
}
static HB_PSIZE_FUNC( hb_p_pushblock )
@@ -70,6 +82,12 @@ static HB_PSIZE_FUNC( hb_p_pushblockshort )
return pFunc->pCode[ lPCodePos + 1 ];
}
static HB_PSIZE_FUNC( hb_p_pushblocklarge )
{
HB_SYMBOL_UNUSED( cargo );
return HB_PCODE_MKUINT24( &pFunc->pCode[ lPCodePos + 1 ] );
}
static HB_PSIZE_FUNC( hb_p_localname )
{
ULONG ulStart = lPCodePos;
@@ -256,7 +274,20 @@ const BYTE hb_comp_pcode_len[] = {
3, /* HB_P_MACROSEND, */
1, /* HB_P_PUSHOVARREF, */
1, /* HB_P_ARRAYPUSHREF */
3 /* HB_P_VFRAME */
3, /* HB_P_VFRAME */
4, /* HB_P_LARGEFRAME */
4, /* HB_P_LARGEVFRAME */
0, /* HB_P_PUSHSTRHIDDEN */
5, /* HB_P_LOCALADDINT */
1, /* HB_P_MODEQPOP */
1, /* HB_P_EXPEQPOP */
1, /* HB_P_MODEQ */
1, /* HB_P_EXPEQ */
1, /* HB_P_DUPLUNREF */
0, /* HB_P_MPUSHBLOCKLARGE, */
0, /* HB_P_MPUSHSTRLARGE */
0, /* HB_P_PUSHBLOCKLAREG, */
0 /* HB_P_PUSHSTRLARGE */
};
/*
@@ -417,7 +448,20 @@ static HB_PCODE_FUNC_PTR s_psize_table[] =
NULL, /* HB_P_MACROSEND */
NULL, /* HB_P_PUSHOVARREF */
NULL, /* HB_P_ARRAYPUSHREF */
NULL /* HB_P_VFRAME */
NULL, /* HB_P_VFRAME */
NULL, /* HB_P_LARGEFRAME */
NULL, /* HB_P_LARGEVFRAME */
hb_p_pushstrhidden, /* HB_P_PUSHSTRHIDDEN */
NULL, /* HB_P_LOCALADDINT */
NULL, /* HB_P_MODEQPOP */
NULL, /* HB_P_EXPEQPOP */
NULL, /* HB_P_MODEQ */
NULL, /* HB_P_EXPEQ */
NULL, /* HB_P_DUPLUNREF */
NULL, /* HB_P_MPUSHBLOCKLARGE */
NULL, /* HB_P_MPUSHSTRLARGE */
hb_p_pushblocklarge, /* HB_P_PUSHBLOCKLARGE, */
hb_p_pushstrlarge /* HB_P_PUSHSTRLARGE */
};
LONG hb_compPCodeSize( PFUNCTION pFunc, ULONG ulOffset )

View File

@@ -228,7 +228,20 @@ static PHB_STRIP_FUNC s_stripLines_table[] =
NULL, /* HB_P_MACROSEND */
NULL, /* HB_P_PUSHOVARREF */
NULL, /* HB_P_ARRAYPUSHREF */
NULL /* HB_P_VFRAME */
NULL, /* HB_P_VFRAME */
NULL, /* HB_P_LARGEFRAME */
NULL, /* HB_P_LARGEVFRAME */
NULL, /* HB_P_PUSHSTRHIDDEN */
NULL, /* HB_P_LOCALADDINT */
NULL, /* HB_P_MODEQPOP */
NULL, /* HB_P_EXPEQPOP */
NULL, /* HB_P_MODEQ */
NULL, /* HB_P_EXPEQ */
NULL, /* HB_P_DUPLUNREF */
NULL, /* HB_P_MPUSHBLOCKLARGE */
NULL, /* HB_P_MPUSHSTRLARGE */
NULL, /* HB_P_PUSHBLOCKLARGE */
NULL /* HB_P_PUSHSTRLARGE */
};
void hb_compStripFuncLines( PFUNCTION pFunc )

View File

@@ -56,9 +56,8 @@
*/
/* TODO list
* 1) jumps longer then 2^15 bytes
* 2) Change the pcode generated by ::cVar from Self:cVar to QSELF():cVar
* 3) Support this syntax: nPtr := @Hello()
* 1) Change the pcode generated by ::cVar from Self:cVar to QSELF():cVar
* 2) Support this syntax: nPtr := @Hello()
*/
/* this #define HAVE TO be placed before all #include directives

File diff suppressed because it is too large Load Diff

View File

@@ -120,7 +120,7 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
#line 121 "macro.y"
#line 120 "macro.y"
{
char * string; /* to hold a string returned by lex */
int iNumber; /* to hold a temporary integer number */

View File

@@ -354,7 +354,7 @@ HB_FUNC( __EJECT ) /* Ejects the current page from the printer */
{
if( hb_set.hb_set_printhan != FS_ERROR && hb_stricmp( hb_set.HB_SET_DEVICE, "PRINTER" ) == 0 )
{
static const BYTE byEop[ 2 ] = { 0x0C, 0x0D };
static const BYTE byEop[ 4 ] = { 0x0C, 0x0D, 0x00, 0x00 };
USHORT uiErrorOld = hb_fsError(); /* Save current user file error code */
hb_fsWrite( hb_set.hb_set_printhan, byEop, 2 );
hb_fsSetError( uiErrorOld ); /* Restore last user file error code */

View File

@@ -327,7 +327,7 @@ static BOOL DPGetDefaultPrinter(LPTSTR pPrinterName, LPDWORD pdwBufferSize)
{
BOOL bFlag;
OSVERSIONINFO osv;
TCHAR cBuffer[MAXBUFFERSIZE];
TCHAR cBuffer[MAXBUFFERSIZE], *ptr;
PRINTER_INFO_2 *ppi2 = NULL;
DWORD dwNeeded = 0;
DWORD dwReturned = 0;
@@ -396,7 +396,16 @@ static BOOL DPGetDefaultPrinter(LPTSTR pPrinterName, LPDWORD pdwBufferSize)
return FALSE;
/* Printer name precedes first "," character... */
strtok(cBuffer, ",");
ptr = cBuffer;
while( *ptr )
{
if( *ptr == ',' )
{
*ptr = '\0';
break;
}
++ptr;
}
/* If given buffer too small, set required size and fail... */
if ((DWORD)lstrlen(cBuffer) >= *pdwBufferSize)

View File

@@ -63,13 +63,16 @@ HB_FUNC( LEFT )
if( pText && ISNUM( 2 ) )
{
long lLen = hb_parnl( 2 );
if( lLen > ( long ) hb_itemGetCLen( pText ) )
lLen = ( long ) hb_itemGetCLen( pText );
else if( lLen < 0 )
lLen = 0;
hb_retclen( hb_itemGetCPtr( pText ), lLen );
if( lLen < 0 )
hb_retc( NULL );
else
{
ULONG ulText = hb_itemGetCLen( pText );
if( ( ULONG ) lLen >= ulText )
hb_itemReturn( pText );
else
hb_retclen( hb_itemGetCPtr( pText ), lLen );
}
}
else
hb_errRT_BASE_SubstR( EG_ARG, 1124, NULL, "LEFT", 2, hb_paramError( 1 ), hb_paramError( 2 ) );

View File

@@ -63,16 +63,17 @@ HB_FUNC( RIGHT )
if( pText && ISNUM( 2 ) )
{
long lLen = hb_parnl( 2 );
long lTextLen = ( long ) hb_itemGetCLen( pText );
if( lLen > lTextLen )
lLen = lTextLen;
else if( lLen < 0 )
lLen = 0;
hb_retclen( hb_itemGetCPtr( pText ) + lTextLen - lLen, lLen );
if( lLen < 0 )
hb_retc( NULL );
else
{
ULONG ulText = hb_itemGetCLen( pText );
if( ( ULONG ) lLen >= ulText )
hb_itemReturn( pText );
else
hb_retclen( hb_itemGetCPtr( pText ) + ulText - lLen, lLen );
}
}
else
hb_retc( NULL ); /* Clipper doesn't error */
}

View File

@@ -122,10 +122,12 @@ HB_FUNC( STRTRAN )
long lReplaced = 0;
ULONG i = 0;
ULONG ulLength = ulText;
ULONG ulStop = ulText - ulSeek + 1;
while( i < ulText )
while( i < ulStop )
{
if( ( bAll || lReplaced < ( long ) ulCount ) && ! memcmp( szText + i, szSeek, ulSeek ) )
if( ( bAll || lReplaced < ( long ) ulCount ) &&
! memcmp( szText + i, szSeek, ulSeek ) )
{
ulFound++;
if( ulFound >= ulStart )
@@ -177,16 +179,16 @@ HB_FUNC( STRTRAN )
hb_retclen_buffer( szResult, ulLength );
}
else
hb_retclen( szText, ulText );
hb_itemReturn( pText );
}
else
hb_retclen( szText, ulText );
hb_itemReturn( pText );
}
else
hb_retclen( szText, ulText );
hb_itemReturn( pText );
}
else
hb_retclen( szText, ulText );
hb_itemReturn( pText );
}
else
hb_errRT_BASE_SubstR( EG_ARG, 1126, NULL, "STRTRAN", HB_ERR_ARGS_BASEPARAMS ); /* NOTE: Undocumented but existing Clipper Run-time error [vszakats] */

View File

@@ -118,13 +118,13 @@ HB_CODEBLOCK_PTR hb_codeblockNew( const BYTE * pBuffer,
USHORT uiLocals,
const BYTE * pLocalPosTable,
PHB_SYMB pSymbols,
USHORT usLen )
ULONG ulLen )
{
HB_CODEBLOCK_PTR pCBlock;
PHB_ITEM pLocals;
BYTE * pCode;
HB_TRACE(HB_TR_DEBUG, ("hb_codeblockNew(%p, %hu, %p, %p, %hu)", pBuffer, uiLocals, pLocalPosTable, pSymbols, usLen));
HB_TRACE(HB_TR_DEBUG, ("hb_codeblockNew(%p, %hu, %p, %p, %lu)", pBuffer, uiLocals, pLocalPosTable, pSymbols, ulLen));
/*
* allocate memory for code block body and detach items hb_gcAlloc()
@@ -132,15 +132,15 @@ HB_CODEBLOCK_PTR hb_codeblockNew( const BYTE * pBuffer,
* calling hb_gcLock()/hb_gcUnlock(). [druzus]
*/
if( usLen )
if( ulLen )
{
/*
* The codeblock pcode is stored in dynamically allocated memory that
* can be deallocated after creation of a codeblock. We have to duplicate
* the passed buffer
*/
pCode = ( BYTE * ) hb_xgrab( usLen );
memcpy( pCode, pBuffer, usLen );
pCode = ( BYTE * ) hb_xgrab( ulLen );
memcpy( pCode, pBuffer, ulLen );
}
else
{
@@ -216,7 +216,7 @@ HB_CODEBLOCK_PTR hb_codeblockNew( const BYTE * pBuffer,
pCBlock = ( HB_CODEBLOCK_PTR ) hb_gcAlloc( sizeof( HB_CODEBLOCK ), hb_codeblockDeleteGarbage );
pCBlock->pCode = pCode;
pCBlock->dynBuffer = usLen != 0;
pCBlock->dynBuffer = ulLen != 0;
pCBlock->pDefSymb = hb_stackBaseItem()->item.asSymbol.value;
pCBlock->pSymbols = pSymbols;
pCBlock->lStatics = hb_stackGetStaticsBase();
@@ -228,12 +228,12 @@ HB_CODEBLOCK_PTR hb_codeblockNew( const BYTE * pBuffer,
return pCBlock;
}
HB_CODEBLOCK_PTR hb_codeblockMacroNew( BYTE * pBuffer, USHORT usLen )
HB_CODEBLOCK_PTR hb_codeblockMacroNew( BYTE * pBuffer, ULONG ulLen )
{
HB_CODEBLOCK_PTR pCBlock;
BYTE * pCode;
HB_TRACE(HB_TR_DEBUG, ("hb_codeblockMacroNew(%p, %i)", pBuffer, usLen));
HB_TRACE(HB_TR_DEBUG, ("hb_codeblockMacroNew(%p, %lu)", pBuffer, ulLen));
/*
* The codeblock pcode is stored in dynamically allocated memory that
@@ -245,8 +245,8 @@ HB_CODEBLOCK_PTR hb_codeblockMacroNew( BYTE * pBuffer, USHORT usLen )
* to be safe for automatic GC activation in hb_xgrab() without
* calling hb_gcLock()/hb_gcUnlock(). [druzus]
*/
pCode = ( BYTE * ) hb_xgrab( usLen );
memcpy( pCode, pBuffer, usLen );
pCode = ( BYTE * ) hb_xgrab( ulLen );
memcpy( pCode, pBuffer, ulLen );
pCBlock = ( HB_CODEBLOCK_PTR ) hb_gcAlloc( sizeof( HB_CODEBLOCK ), hb_codeblockDeleteGarbage );
/* Store the number of referenced local variables */

File diff suppressed because it is too large Load Diff

View File

@@ -964,26 +964,50 @@ int hb_compLocalVarGetPos( char * szVarName, HB_COMP_DECL )
ULONG hb_compGenJump( LONG lOffset, HB_COMP_DECL )
{
/* TODO: We need a longer offset (longer then two bytes)
*/
if ( ! HB_LIM_INT16( lOffset ) )
if( lOffset == 0 )
hb_compGenPCode4( HB_P_JUMPFAR, 0, 0, 0, HB_COMP_PARAM );
else if( HB_LIM_INT8( lOffset ) )
hb_compGenPCode2( HB_P_JUMPNEAR, HB_LOBYTE( lOffset ), HB_COMP_PARAM );
else if( HB_LIM_INT16( lOffset ) )
hb_compGenPCode3( HB_P_JUMP, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), HB_COMP_PARAM );
else if( HB_LIM_INT24( lOffset ) )
hb_compGenPCode4( HB_P_JUMPFAR, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), HB_ULBYTE( lOffset ), HB_COMP_PARAM );
else
hb_macroError( HB_MACRO_TOO_COMPLEX, HB_COMP_PARAM );
hb_compGenPCode3( HB_P_JUMP, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), HB_COMP_PARAM );
return HB_PCODE_DATA->lPCodePos - 2;
return HB_PCODE_DATA->lPCodePos - 3;
}
ULONG hb_compGenJumpFalse( LONG lOffset, HB_COMP_DECL )
{
/* TODO: We need a longer offset (longer then two bytes)
*/
if ( ! HB_LIM_INT16( lOffset ) )
if( lOffset == 0 )
hb_compGenPCode4( HB_P_JUMPFALSEFAR, 0, 0, 0, HB_COMP_PARAM );
else if( HB_LIM_INT8( lOffset ) )
hb_compGenPCode2( HB_P_JUMPFALSENEAR, HB_LOBYTE( lOffset ), HB_COMP_PARAM );
else if( HB_LIM_INT16( lOffset ) )
hb_compGenPCode3( HB_P_JUMPFALSE, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), HB_COMP_PARAM );
else if( HB_LIM_INT24( lOffset ) )
hb_compGenPCode4( HB_P_JUMPFALSEFAR, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), HB_ULBYTE( lOffset ), HB_COMP_PARAM );
else
hb_macroError( HB_MACRO_TOO_COMPLEX, HB_COMP_PARAM );
hb_compGenPCode3( HB_P_JUMPFALSE, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), HB_COMP_PARAM );
return HB_PCODE_DATA->lPCodePos - 3;
}
return HB_PCODE_DATA->lPCodePos - 2;
ULONG hb_compGenJumpTrue( LONG lOffset, HB_COMP_DECL )
{
if( lOffset == 0 )
hb_compGenPCode4( HB_P_JUMPTRUEFAR, 0, 0, 0, HB_COMP_PARAM );
else if( HB_LIM_INT8( lOffset ) )
hb_compGenPCode2( HB_P_JUMPTRUENEAR, HB_LOBYTE( lOffset ), HB_COMP_PARAM );
else if( HB_LIM_INT16( lOffset ) )
hb_compGenPCode3( HB_P_JUMPTRUE, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), HB_COMP_PARAM );
else if( HB_LIM_INT24( lOffset ) )
hb_compGenPCode4( HB_P_JUMPTRUEFAR, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), HB_ULBYTE( lOffset ), HB_COMP_PARAM );
else
hb_macroError( HB_MACRO_TOO_COMPLEX, HB_COMP_PARAM );
return HB_PCODE_DATA->lPCodePos - 3;
}
void hb_compGenJumpThere( ULONG ulFrom, ULONG ulTo, HB_COMP_DECL )
@@ -991,13 +1015,10 @@ void hb_compGenJumpThere( ULONG ulFrom, ULONG ulTo, HB_COMP_DECL )
BYTE * pCode = HB_PCODE_DATA->pCode;
LONG lOffset = ulTo - ulFrom + 1;
/* TODO: We need a longer offset (longer then two bytes)
*/
if ( ! HB_LIM_INT16( lOffset ) )
if( HB_LIM_INT24( lOffset ) )
HB_PUT_LE_UINT24( &pCode[ ulFrom ], lOffset );
else
hb_macroError( HB_MACRO_TOO_COMPLEX, HB_COMP_PARAM );
pCode[ ( ULONG ) ulFrom ] = HB_LOBYTE( lOffset );
pCode[ ( ULONG ) ulFrom + 1 ] = HB_HIBYTE( lOffset );
}
void hb_compGenJumpHere( ULONG ulOffset, HB_COMP_DECL )
@@ -1005,18 +1026,6 @@ void hb_compGenJumpHere( ULONG ulOffset, HB_COMP_DECL )
hb_compGenJumpThere( ulOffset, HB_PCODE_DATA->lPCodePos, HB_COMP_PARAM );
}
ULONG hb_compGenJumpTrue( LONG lOffset, HB_COMP_DECL )
{
/* TODO: We need a longer offset (longer then two bytes)
*/
if ( ! HB_LIM_INT16( lOffset ) )
hb_macroError( HB_MACRO_TOO_COMPLEX, HB_COMP_PARAM );
hb_compGenPCode3( HB_P_JUMPTRUE, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), HB_COMP_PARAM );
return HB_PCODE_DATA->lPCodePos - 2;
}
/* Checks if there is a visible memvar variable
* szVarName = variable name
*/
@@ -1392,8 +1401,16 @@ void hb_compGenPushFunCall( char * szFunName, HB_COMP_DECL )
/* generates the pcode to push a string on the virtual machine stack */
void hb_compGenPushString( char * szText, ULONG ulStrLen, HB_COMP_DECL )
{
hb_compGenPCode3( HB_P_MPUSHSTR, HB_LOBYTE( ulStrLen ), HB_HIBYTE( ulStrLen ), HB_COMP_PARAM );
hb_compGenPCodeN( ( BYTE * ) szText, ulStrLen, HB_COMP_PARAM );
if( ulStrLen <= UINT24_MAX )
{
if( ulStrLen <= USHRT_MAX )
hb_compGenPCode3( HB_P_MPUSHSTR, HB_LOBYTE( ulStrLen ), HB_HIBYTE( ulStrLen ), HB_COMP_PARAM );
else
hb_compGenPCode4( HB_P_MPUSHSTRLARGE, HB_LOBYTE( ulStrLen ), HB_HIBYTE( ulStrLen ), HB_ULBYTE( ulStrLen ), HB_COMP_PARAM );
hb_compGenPCodeN( ( BYTE * ) szText, ulStrLen, HB_COMP_PARAM );
}
else
hb_macroError( HB_MACRO_TOO_COMPLEX, HB_COMP_PARAM );
}
@@ -1492,7 +1509,7 @@ void hb_compCodeBlockStart( HB_COMP_DECL )
void hb_compCodeBlockEnd( HB_COMP_DECL )
{
HB_PCODE_INFO_PTR pCodeblock; /* pointer to the current codeblock */
USHORT wSize;
ULONG ulSize;
USHORT wParms = 0; /* number of codeblock parameters */
HB_CBVAR_PTR pVar;
@@ -1509,9 +1526,6 @@ void hb_compCodeBlockEnd( HB_COMP_DECL )
/* generate a proper codeblock frame with a codeblock size and with
* a number of expected parameters
*/
/*QUESTION: would be 64kB enough for a codeblock size?
* we are assuming now a USHORT for a size of codeblock
*/
/* Count the number of codeblock parameters */
pVar = pCodeblock->pLocals;
@@ -1525,14 +1539,19 @@ void hb_compCodeBlockEnd( HB_COMP_DECL )
* runtime compiled codeblock cannot reference local variables defined in a
* function
*/
wSize = ( USHORT ) pCodeblock->lPCodePos + 6;
ulSize = ( ULONG ) pCodeblock->lPCodePos + 6;
/*NOTE: HB_P_MPUSHBLOCK differs from HB_P_PUSHBLOCK - the pcode
* is stored in dynamic memory pool instead of static memory
*/
hb_compGenPCode3( HB_P_MPUSHBLOCK, HB_LOBYTE( wSize ), HB_HIBYTE( wSize ), HB_COMP_PARAM );
hb_compGenPCode1( HB_LOBYTE( wParms ), HB_COMP_PARAM );
hb_compGenPCode1( HB_HIBYTE( wParms ), HB_COMP_PARAM );
if( ulSize <= USHRT_MAX )
hb_compGenPCode3( HB_P_MPUSHBLOCK, HB_LOBYTE( ulSize ), HB_HIBYTE( ulSize ), HB_COMP_PARAM );
else
{
++ulSize;
hb_compGenPCode4( HB_P_MPUSHBLOCKLARGE, HB_LOBYTE( ulSize ), HB_HIBYTE( ulSize ), HB_ULBYTE( ulSize ), HB_COMP_PARAM );
}
hb_compGenPCode2( HB_LOBYTE( wParms ), HB_HIBYTE( wParms ), HB_COMP_PARAM );
/* copy a codeblock pcode buffer */
hb_compGenPCodeN( pCodeblock->pCode, pCodeblock->lPCodePos, HB_COMP_PARAM );